#!/usr/bin/env python

import argparse
import os
import subprocess
import sys
import typing
from binascii import hexlify, unhexlify
from enum import Enum

copyrightNotice = """/*
 *
 *    Copyright (c) 2022 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * NOTE: This file is generated by src/tools/chip-cert/dacs.py.
 */
"""


def bytes_from_hex(hex: str) -> bytes:
    """Converts any `hex` string representation including `01:ab:cd` to bytes

    Handles any whitespace including newlines, which are all stripped.
    """
    return unhexlify("".join(hex.replace(":", "").split()))


def make_c_array(byte_string: bytes, name: str, linelen: int) -> str:
    """Convert a large byte string to a named constant C/C++ uint8_t array. """
    def _extract_front(b: bytes, length: int) -> bytes:
        to_extract = min(length, len(b))
        span = b[0:to_extract]
        del b[0:to_extract]

        return span

    byte_string = bytearray(byte_string)
    output = "const uint8_t %s[%d] = {\n" % (name, len(byte_string))
    while len(byte_string) > 0:
        current_line_bytes = _extract_front(byte_string, linelen)
        output += "    %s,\n" % ", ".join(["0x%02x" %
                                          b for b in current_line_bytes])
    output += "};\n"

    return output


def make_array_header(byte_string: bytes, name: str) -> str:
    """Returns the header define for an array with the given name and size."""
    byte_string = bytearray(byte_string)
    return 'extern const uint8_t ' + name + '[{:d}];\n'.format(len(byte_string))


def open_outfile(filename=None) -> typing.BinaryIO:
    """Opens either a file or stdout for output."""
    if filename:
        fh = open(filename, 'wb')
    else:
        fh = sys.stdout

    try:
        yield fh
    finally:
        if fh is not sys.stdout:
            fh.close()


class CertType(Enum):
    PAA = 1
    PAI = 2
    DAC = 3


class Names:
    def __init__(self, cert_type: CertType, test_dir, dev_dir, vid, pid):
        if vid == 0xFFF1:
            paa_file_prefix = 'Chip-Test-PAA-FFF1-'
        else:
            paa_file_prefix = 'Chip-Test-PAA-NoVID-'
        prefixes = {CertType.PAA: test_dir + paa_file_prefix,
                    CertType.PAI: dev_dir + '/Matter-Development-PAI-{:X}-noPID-'.format(vid),
                    CertType.DAC: dev_dir + '/Matter-Development-DAC-{:X}-{:X}-'.format(vid, pid)}
        array_names_prefix = {CertType.PAA: 'kTestPAA_',
                              CertType.PAI: 'kDevelopmentPAI_',
                              CertType.DAC: 'kDevelopmentDAC_'}
        array_names_suffix = {CertType.PAA: '',
                              CertType.PAI: '_{:X}'.format(vid),
                              CertType.DAC: '_{:X}_{:X}'.format(vid, pid)}
        generic_prefix = {CertType.PAA: 'kPaa',
                          CertType.PAI: 'kPai',
                          CertType.DAC: 'kDac'}

        prefix = prefixes[cert_type]
        array_name_prefix = array_names_prefix[cert_type]
        array_name_suffix = array_names_suffix[cert_type]

        self.cert_pem = prefix + 'Cert.pem'
        self.cert_der = prefix + 'Cert.der'
        self.key_pem = prefix + 'Key.pem'
        self.key_der = prefix + 'Key.der'
        self.public_key_array_name = array_name_prefix + 'PublicKey' + array_name_suffix
        self.private_key_array_name = array_name_prefix + 'PrivateKey' + array_name_suffix
        self.cert_array_name = array_name_prefix + 'Cert' + array_name_suffix
        self.generic_prefix = generic_prefix[cert_type]


class DevCertBuilder:
    def __init__(self, cert_type: CertType, dev_dir: str, test_dir: str, chip_cert_dir: str, vid: int, pid: int):
        self.vid = vid
        self.pid = pid
        self.cert_type = cert_type
        self.chipcert = chip_cert_dir + 'chip-cert'

        if not os.path.exists(self.chipcert):
            raise Exception('Path not found: %s' % self.chipcert)

        paa = Names(CertType.PAA, test_dir, dev_dir, vid, pid)
        pai = Names(CertType.PAI, test_dir, dev_dir, vid, pid)
        dac = Names(CertType.DAC, test_dir, dev_dir, vid, pid)
        if cert_type == CertType.PAI:
            self.signer = paa
            self.own = pai
        if cert_type == CertType.DAC:
            self.signer = pai
            self.own = dac

    def make_certs_and_keys(self) -> None:
        """Creates the PEM and DER certs and keyfiles"""
        if self.cert_type == CertType.PAI:
            subject_name = 'Matter Dev PAI 0x{:X} no PID'.format(self.vid)
            pid_flag = ''
            type_flag = '-t i'
            vidpid_fallback_encoding_flag = ''
        elif self.cert_type == CertType.DAC:
            subject_name = 'Matter Dev DAC 0x{:X}/0x{:X}'.format(self.vid, self.pid)
            pid_flag = '-P 0x{:X}'.format(self.pid)
            type_flag = '-t d'
            # For a subset of DACs with PIDs in a range [0x8010, 0x8014]
            # use alternative (fallback) PID/VID encoding method.
            if self.pid >= 0x8010 and self.pid <= 0x8014:
                vidpid_fallback_encoding_flag = ' -a'
            else:
                vidpid_fallback_encoding_flag = ''
        else:
            return

        cmd = self.chipcert + ' gen-att-cert ' + type_flag + ' -c "' + subject_name + '" -C ' + self.signer.cert_pem + ' -K ' + \
            self.signer.key_pem + ' -V 0x{:X} '.format(self.vid) + pid_flag + vidpid_fallback_encoding_flag + \
            ' -l 4294967295 -o ' + self.own.cert_pem + ' -O ' + self.own.key_pem
        subprocess.run(cmd, shell=True)
        cmd = 'openssl x509 -inform pem -in ' + self.own.cert_pem + \
            ' -out ' + self.own.cert_der + ' -outform DER'
        subprocess.run(cmd, shell=True)
        cmd = 'openssl ec -inform pem -in ' + self.own.key_pem + \
            ' -out ' + self.own.key_der + ' -outform DER'
        subprocess.run(cmd, shell=True)

    def get_raw_keys(self) -> tuple[str, str]:
        """Extracts the raw key bytes from the PEM file"""
        cmd = 'openssl ec -inform pem -in ' + self.own.key_pem + ' -text'
        out = subprocess.run(
            cmd, shell=True, capture_output=True).stdout.decode('utf-8')
        priv = ''.join(out[out.find('priv:')+5:out.find('pub:')].split())
        pub = ''.join(out[out.find('pub:')+4:out.find('ASN1')].split())
        return [bytes_from_hex(pub), bytes_from_hex(priv)]

    def full_arrays(self) -> tuple[str, str]:
        """Returns the byte arrays and declarations"""
        with open(self.own.cert_der, "rb") as infile:
            b = infile.read()
            cert = make_c_array(b, self.own.cert_array_name, 21)
            header = make_array_header(b, self.own.cert_array_name)

        [pub, priv] = self.get_raw_keys()
        h_pub = 'extern const uint8_t ' + \
            self.own.public_key_array_name + '[65];\n'
        h_priv = 'extern const uint8_t ' + \
            self.own.private_key_array_name + '[32];\n'

        c = cert + make_c_array(pub, self.own.public_key_array_name, 17) + \
            make_c_array(priv, self.own.private_key_array_name, 16)
        h = header + h_pub + h_priv
        return [h, c]

    def generic_arrays(self) -> tuple[str, str]:
        """Returns the generic refernce for Certs and Keys of this type"""
        h_start = 'extern ByteSpan ' + self.own.generic_prefix
        h = h_start + 'Cert;\n' + h_start + 'PublicKey;\n' + h_start + 'PrivateKey;\n\n'
        c_start = 'ByteSpan ' + self.own.generic_prefix
        cert = c_start + \
            'Cert       = ByteSpan(' + self.own.cert_array_name + ');\n'
        priv = c_start + \
            'PrivateKey = ByteSpan(' + self.own.private_key_array_name + ');\n'
        publ = c_start + \
            'PublicKey  = ByteSpan(' + self.own.public_key_array_name + ');\n'
        c = cert + priv + publ
        return [h, c]

    def headers(self, filename) -> tuple[str, str]:
        """Returns a string with the headers for the output files"""
        includes = '#include <cstdint>\n\n#include <lib/support/Span.h>\n#include <platform/CHIPDeviceConfig.h>\n\n'
        namespaces = 'namespace chip {\nnamespace DevelopmentCerts {\n\n'
        h_top = copyrightNotice + '#pragma once\n' + includes + namespaces

        c_top = copyrightNotice + '#include "' + \
            filename + '.h"\n\n' + includes + namespaces
        return [h_top, c_top]

    def footer(self) -> str:
        """Returns the footer for the output files"""
        return '} // namespace DevelopmentCerts\n} // namespace chip\n'


def main():
    argparser = argparse.ArgumentParser()
    argparser.add_argument('-d', '--dev_dir', dest='certdir',
                           default='credentials/development/attestation',
                           help='output directory for PEM and DER files')
    argparser.add_argument('-t', '--test_dir', dest='testdir',
                           default='credentials/test/attestation/', help='directory holding test PAA')
    argparser.add_argument('-o', '--out_dir', dest='outdir',
                           default='src/credentials/examples/', help='Output directory for array files')
    argparser.add_argument('-c', '--chip-cert_dir', dest='chipcertdir',
                           default='out/debug/standalone/', help='Directory where chip-cert tool is located')
    argparser.add_argument('--paiout', dest='paiout', default='ExamplePAI',
                           help='output file name for PAI C arrays (no .h or .cpp extension)')
    argparser.add_argument('--dacout', dest='dacout', default='ExampleDACs',
                           help='output file name for PAI C arrays (no .h or .cpp extension)')

    args = argparser.parse_args()
    builder = DevCertBuilder(CertType.PAI, args.certdir,
                             args.testdir, args.chipcertdir, 0xFFF1, 0x8000)

    builder.make_certs_and_keys()
    [h_generic, c_generic] = builder.generic_arrays()
    [h_top, c_top] = builder.headers(args.paiout)
    footer = builder.footer()
    with open(args.outdir + args.paiout + '.h', "w") as hfile:
        with open(args.outdir + args.paiout + '.cpp', "w") as cfile:
            hfile.write(h_top)
            hfile.write(h_generic)
            cfile.write(c_top)

            for vid in range(0xFFF1, 0xFFF4):
                builder = DevCertBuilder(CertType.PAI, args.certdir,
                                         args.testdir, args.chipcertdir, vid, 0x8000)
                builder.make_certs_and_keys()
                [h_full, c_full] = builder.full_arrays()
                [h_generic, c_generic] = builder.generic_arrays()

                define = '#if CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID == 0x{:X}\n'.format(vid)
                end = '#endif\n'

                hfile.write(define)
                hfile.write(h_full)
                hfile.write(end)

                cfile.write(define)
                cfile.write(c_full)
                cfile.write(c_generic)
                cfile.write(end)

            hfile.write(footer)
            cfile.write(footer)

    with open(args.outdir + args.dacout + '.h', "w") as hfile:
        with open(args.outdir + args.dacout + '.cpp', "w") as cfile:
            builder = DevCertBuilder(
                CertType.DAC, args.certdir, args.testdir, args.chipcertdir, 0xFFF1, 0x8000)
            [h_top, c_top] = builder.headers(args.dacout)
            [h_generic, c_generic] = builder.generic_arrays()
            footer = builder.footer()

            hfile.write(h_top)
            hfile.write(h_generic)
            cfile.write(c_top)

            for vid in range(0xFFF1, 0xFFF4):
                for pid in range(0x8000, 0x8020):
                    builder = DevCertBuilder(
                        CertType.DAC, args.certdir, args.testdir, args.chipcertdir, vid, pid)
                    builder.make_certs_and_keys()
                    [h, c] = builder.full_arrays()
                    [h_generic, c_generic] = builder.generic_arrays()

                    define = '#if CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID == 0x{:X} && CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID == 0x{:X}\n'.format(
                        vid, pid)
                    end = '#endif\n'

                    hfile.write(define)
                    hfile.write(h)
                    hfile.write(end)

                    cfile.write(define)
                    cfile.write(c)
                    cfile.write(c_generic)
                    cfile.write(end)

            hfile.write(footer)
            cfile.write(footer)


if __name__ == '__main__':
    sys.exit(main())
