#!/usr/bin/env python3.8
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import re
import sys
import subprocess

_FILE_HEADER = """// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of zircon;

// This is autogenerated from Zircon headers. Do not edit directly.
// Generated by //sdk/dart/zircon/extract-zircon-constants.py

// ignore_for_file: constant_identifier_names
// ignore_for_file: public_member_api_docs
"""

_PREFIX = 'ZX_'


def read_header(header):
    """Read lines from a C header handle macro continuation backslashes."""
    continuation = ''
    for line in open(header):
        line = line.rstrip()
        if continuation:
            line = continuation + ' ' + line.lstrip()
        if line.endswith('\\'):
            continuation = (line[:-1]).rstrip()
            continue
        else:
            continuation = ''
            yield line
    assert continuation == ''


def extract_defines(header, guard):
    """Extract the C macro defines from a header file."""
    defines = []
    for line in read_header(header):
        line = line.rstrip()
        if not line.startswith('#define'):
            continue
        match = re.match(
            r'#define\s+(?P<symbol>[A-Z0-9_]+)\s+(?P<value>\S.*)', line)
        if match:
            defines.append(
                (match.groupdict()['symbol'], match.groupdict()['value']))
        else:
            # ignore the header guard
            if line.startswith(f'#define {guard}') or \
                line.startswith(f'#define SYSROOT_{guard}'):
                continue
            # ignore function-like macros
            if not re.match(r'#define\s+[A-Za-z0-9_]+\(', line):
                raise ValueError(f'Unrecognized line: {line} in {header}')

    # quadratic time is best time
    public_constants = [
        (k[len(_PREFIX):], c_to_dart_value(v, defines))
        for k, v in defines
        if k.startswith(_PREFIX)
    ]
    private_constants = [
        (k, c_to_dart_value(v, defines))
        for k, v in defines
        if not k.startswith(_PREFIX)
    ]
    return public_constants + private_constants


def c_to_dart_value(value, defines):
    """Convert a C macro value to something that can be a Dart constant."""
    # strip type casts
    value = re.sub(r'\([a-z0-9_]+_t\)', '', value)

    # strip u suffix from decimal integers
    value = re.sub(r'([0-9]+)u', r'\1', value)

    # strip u suffix from hex integers
    value = re.sub(r'(0x[a-fA-F0-9]+)u', r'\1', value)

    # replace a C constant that's used in the headers
    value = re.sub(r'UINT64_MAX', r'0xFFFFFFFFFFFFFFFF', value)

    # strip outer parens
    value = re.sub(r'^\((.*)\)$', r'\1', value)

    # strip _PREFIX from references to other constants
    value = re.sub(r'\b' + _PREFIX + r'(\w*)\b', r'\1', value)

    return value


class DartWriter(object):

    def __init__(self, path, dart):
        dest = open(path, 'w')

        # The undocumented --no-analytics flag is the only way to avoid
        # the creation of $BUILD_DIR/.dart/ when 'dart format' is called.
        # See https://fxbug.dev/80787 for details.
        self.popen = subprocess.Popen(
            [dart, '--no-analytics', 'format', '-o', 'show'],
            stdin=subprocess.PIPE,
            stdout=dest,
            text=True)

    def write(self, string):
        self.popen.stdin.write(string)

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.popen.stdin.close()
        self.popen.wait()
        assert self.popen.returncode == 0


def write_constants(
        zircon_errors, zircon_types, zircon_rights, dart_constants, dart):
    error_defines = extract_defines(zircon_errors, 'ZIRCON_ERRORS_H_')
    type_defines = extract_defines(zircon_types, 'ZIRCON_TYPES_H_')
    right_defines = extract_defines(zircon_rights, 'ZIRCON_RIGHTS_H_')
    with DartWriter(dart_constants, dart) as f:
        f.write(_FILE_HEADER)
        f.write('abstract class ZX {\n')
        f.write('  ZX._();')
        for symbol, value in error_defines + type_defines + right_defines:
            # PAGE_SIZE is from limits.h. It contains arch specific defines
            # that are hard to parse here, so skip until affected constants are
            # needed in Dart.
            if value == 'PAGE_SIZE':
                continue
            if symbol.startswith('_'):
                # private constant, it's okay if it's unused.
                f.write('  // ignore: unused_field\n')
            f.write(f'  static const int {symbol} = {value};\n')
        f.write('}\n')

        f.write('String getStringForStatus(int status) {\n')
        f.write('  switch(status) {\n')
        for symbol, value in error_defines:
            f.write(f"    case ZX.{symbol}: return '{symbol}';\n")
        f.write("    default: return '(unknown: $status)';\n")
        f.write('  }\n')
        f.write('}\n')


def main():
    parser = argparse.ArgumentParser(
        description=
        'Generates dart constants from a parsing of corresponding values in zircon'
    )
    parser.add_argument(
        '--errors',
        required=True,
        help='Path to the zircon errors.h header file')
    parser.add_argument(
        '--types', required=True, help='Path to the zircon types.h header file')
    parser.add_argument(
        '--rights',
        required=True,
        help='Path to the zircon rights.h header file')
    parser.add_argument('--dart', required=True, help='Path to the dart tool')
    parser.add_argument(
        '--dart-constants',
        required=True,
        help='Where to generate the dart constants file')
    args = parser.parse_args()

    write_constants(
        zircon_errors=args.errors,
        zircon_types=args.types,
        zircon_rights=args.rights,
        dart_constants=args.dart_constants,
        dart=args.dart,
    )


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