# Copyright 2020 Google LLC
#
# 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
#
#     https://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.
#
# Lint as: python3
"""Generates known_test_values.h from dumped test values.

This program generates the known_test_values.h file used for unit tests. This is
useful to correct the baseline test values based on dumps from the tests. Use
this after fixing a bug in the code, not to 'fix' test breakage not well
understood.

Usage:
  $ cd out
  $ python ../generate_test_values.py > ../include/dice/known_test_values.h

Prerequisites:
  pip install absl-py
"""

from __future__ import print_function

import re
import subprocess
import textwrap

from absl import app
from absl import flags

FLAGS = flags.FLAGS

_FILE_HEADER = textwrap.dedent("""\
    // Copyright 2020 Google LLC
    //
    // 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
    //
    //     https://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.

    // !!! GENERATED - DO NOT MODIFY !!!
    // To update this file, use generate_test_values.py.

    #ifndef DICE_KNOWN_TEST_VALUES_H_
    #define DICE_KNOWN_TEST_VALUES_H_

    #include <stdint.h>

    namespace dice {
    namespace test {

                               """)

_FILE_FOOTER = textwrap.dedent("""\
    }  // namespace test
    }  // namespace dice

    #endif  // DICE_KNOWN_TEST_VALUES_H_
                               """)


def _to_camel_case(s):
    return ''.join(tmp.capitalize() for tmp in s.split('_'))


def _read_file(name):
    try:
        with open(name, 'rb') as f:
            return f.read()
    except OSError:
        return ''


def _generate_array(name, data):
    return 'constexpr uint8_t %s[%d] = {%s};\n\n' % (
        name, len(data), ', '.join('0x%02x' % tmp for tmp in data))


def _generate_cert_comment(data):
    return re.sub('^',
                  '// ',
                  subprocess.run([
                      'openssl', 'x509', '-inform', 'DER', '-noout', '-text',
                      '-certopt', 'ext_parse'
                  ],
                                 input=data,
                                 capture_output=True,
                                 check=True).stdout.decode(),
                  flags=re.MULTILINE)[:-3]


def _generate_c(name):
    """Generates C declarations from dumps identified by |name|."""
    content = ''
    attest_cdi_data = _read_file('_attest_cdi_%s.bin' % name)
    content += _generate_array('kExpectedCdiAttest_%s' % _to_camel_case(name),
                               attest_cdi_data)
    seal_cdi_data = _read_file('_seal_cdi_%s.bin' % name)
    content += _generate_array('kExpectedCdiSeal_%s' % _to_camel_case(name),
                               seal_cdi_data)
    for cert_type in ('X509', 'CBOR'):
        for key_type in ('Ed25519', 'P256', 'P384'):
            var_name = 'kExpected%s%sCert_%s' % (_to_camel_case(cert_type),
                                                 _to_camel_case(key_type),
                                                 _to_camel_case(name))
            cert_data = _read_file('_%s_%s_cert_%s.cert' %
                                   (cert_type, key_type, name))
            if cert_type == 'X509' and key_type != 'P384':
                content += (
                    '// $ openssl x509 -inform DER -noout -text -certopt '
                    'ext_parse\n')
                content += _generate_cert_comment(cert_data)
            content += _generate_array(var_name, cert_data)
    return content


def main(argv):
    if len(argv) > 1:
        raise app.UsageError('Too many command-line arguments.')

    content = _FILE_HEADER
    content += _generate_c('zero_input')
    content += _generate_c('hash_only_input')
    content += _generate_c('descriptor_input')
    content += _FILE_FOOTER
    subprocess.run(['clang-format', '--style=file'],
                   input=content.encode(),
                   check=True)


if __name__ == '__main__':
    app.run(main)
