#!/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 error header file')
parser.add_argument('--types',
                    help='Path to the zircon type 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
if not zircon_errors or not zircon_types:
  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')

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
    if line.endswith('\\'):
      continuation = line[:-1]
      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
  return [(k[prefix_len:], c_to_dart_value(v, defines))
          for k, v in defines
          if k.startswith(prefix)]


def c_to_dart_value(value, defines):
  """Convert a C macro value to something that can be a Dart constant."""
  # expand macro references
  for k, v in defines:
    value = value.replace(k, v)

  # 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)
  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_')
  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:
      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()
