#!/usr/bin/env python
# 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 glob
import os
import re
import sys
import subprocess

parser = argparse.ArgumentParser(
  description="Generates dart constants from a parsing of corresponding values in zircon")
parser.add_argument('--dry-run',
                    help='Whether to run in dry-run mode; if true, no file will be generated',
                    action='store_true')
parser.add_argument('--errors',
                    help='Path to the zircon errors.h header file')
parser.add_argument('--types',
                    help='Path to the zircon types.h header file')
parser.add_argument('--rights',
                    help='Path to the zircon rights.h header file')
parser.add_argument('--dartfmt',
                    help='Path to the dartfmt tool')
parser.add_argument('--dart-constants',
                    help='Where to generate the dart constants file')
parser.set_defaults(dry_run=False)
args = parser.parse_args()

# If args are unset, assume the script is being run out of the checkout.
source_dir = os.path.dirname(__file__)
zircon_errors = args.errors
zircon_types = args.types
zircon_rights = args.rights
if not zircon_errors or not zircon_types or not zircon_rights:
  zircon_include_dir = os.path.join(
      source_dir, '../../../../zircon/system/public/zircon')
  zircon_errors = zircon_errors or os.path.join(zircon_include_dir, 'errors.h')
  zircon_types = zircon_types or os.path.join(zircon_include_dir, 'types.h')
  zircon_rights = zircon_rights or os.path.join(zircon_include_dir, 'rights.h')

dartfmt = args.dartfmt
if not dartfmt:
  dartfmt_globs = glob.glob(os.path.join(
    source_dir, '../../../../prebuilt/third_party/dart/*/bin/dartfmt'))
  dartfmt = dartfmt_globs[0]

dart_constants = args.dart_constants or os.path.join(source_dir, 'lib/src/constants.dart')

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 //topaz/public/dart/zircon/extract-zircon-constants.py

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

prefix = 'ZX_'
prefix_len = len(prefix)


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('#define %s' % guard) or \
          line.startswith('#define SYSROOT_%s' % guard):
        continue
      # ignore function-like macros
      if not re.match(r'#define\s+[A-Za-z0-9_]+\(', line):
        print 'Unrecognized line: %s in %s' % (line, header)
        sys.exit(1)

  # quadratic time is best time
  public_constants = [(k[prefix_len:], 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):
    if args.dry_run:
      path = '/dev/null'
    dest = open(path, 'w')
    self.popen = subprocess.Popen([dartfmt], stdin=subprocess.PIPE, stdout=dest)

  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():
  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) 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:
      if symbol.startswith('_'):
        # private constant, it's okay if it's unused.
        f.write('  // ignore: unused_field\n')
      f.write('  static const int %s = %s;\n' % (symbol, value))
    f.write('}\n')

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


if __name__ == '__main__':
  write_constants()
