#!/usr/bin/env python
#
# Copyright 2014 The Chromium 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 collections
import re
import optparse
import os
from string import Template
import sys

from util import build_utils

# List of C++ types that are compatible with the Java code generated by this
# script.
ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char',
  'short', 'unsigned short',
  'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t']

class EnumDefinition(object):
  def __init__(self, original_enum_name=None, class_name_override=None,
               enum_package=None, entries=None, fixed_type=None):
    self.original_enum_name = original_enum_name
    self.class_name_override = class_name_override
    self.enum_package = enum_package
    self.entries = collections.OrderedDict(entries or [])
    self.prefix_to_strip = None
    self.fixed_type = fixed_type

  def AppendEntry(self, key, value):
    if key in self.entries:
      raise Exception('Multiple definitions of key %s found.' % key)
    self.entries[key] = value

  @property
  def class_name(self):
    return self.class_name_override or self.original_enum_name

  def Finalize(self):
    self._Validate()
    self._AssignEntryIndices()
    self._StripPrefix()

  def _Validate(self):
    assert self.class_name
    assert self.enum_package
    assert self.entries
    if self.fixed_type and self.fixed_type not in ENUM_FIXED_TYPE_WHITELIST:
      raise Exception('Fixed type %s for enum %s not whitelisted.' %
          (self.fixed_type, self.class_name))

  def _AssignEntryIndices(self):
    # Enums, if given no value, are given the value of the previous enum + 1.
    if not all(self.entries.values()):
      prev_enum_value = -1
      for key, value in self.entries.iteritems():
        if not value:
          self.entries[key] = prev_enum_value + 1
        elif value in self.entries:
          self.entries[key] = self.entries[value]
        else:
          try:
            self.entries[key] = int(value)
          except ValueError:
            raise Exception('Could not interpret integer from enum value "%s" '
                            'for key %s.' % (value, key))
        prev_enum_value = self.entries[key]


  def _StripPrefix(self):
    prefix_to_strip = self.prefix_to_strip
    if not prefix_to_strip:
      prefix_to_strip = self.original_enum_name
      prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', prefix_to_strip).upper()
      prefix_to_strip += '_'
      if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]):
        prefix_to_strip = ''

    entries = collections.OrderedDict()
    for (k, v) in self.entries.iteritems():
      stripped_key = k.replace(prefix_to_strip, '', 1)
      if isinstance(v, basestring):
        stripped_value = v.replace(prefix_to_strip, '', 1)
      else:
        stripped_value = v
      entries[stripped_key] = stripped_value

    self.entries = entries

class DirectiveSet(object):
  class_name_override_key = 'CLASS_NAME_OVERRIDE'
  enum_package_key = 'ENUM_PACKAGE'
  prefix_to_strip_key = 'PREFIX_TO_STRIP'

  known_keys = [class_name_override_key, enum_package_key, prefix_to_strip_key]

  def __init__(self):
    self._directives = {}

  def Update(self, key, value):
    if key not in DirectiveSet.known_keys:
      raise Exception("Unknown directive: " + key)
    self._directives[key] = value

  @property
  def empty(self):
    return len(self._directives) == 0

  def UpdateDefinition(self, definition):
    definition.class_name_override = self._directives.get(
        DirectiveSet.class_name_override_key, '')
    definition.enum_package = self._directives.get(
        DirectiveSet.enum_package_key)
    definition.prefix_to_strip = self._directives.get(
        DirectiveSet.prefix_to_strip_key)


class HeaderParser(object):
  single_line_comment_re = re.compile(r'\s*//')
  multi_line_comment_start_re = re.compile(r'\s*/\*')
  enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?')
  enum_end_re = re.compile(r'^\s*}\s*;\.*$')
  generator_directive_re = re.compile(
      r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$')
  multi_line_generator_directive_start_re = re.compile(
      r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$')
  multi_line_directive_continuation_re = re.compile(
      r'^\s*//\s+([\.\w]+)$')
  multi_line_directive_end_re = re.compile(
      r'^\s*//\s+([\.\w]*)\)$')

  optional_class_or_struct_re = r'(class|struct)?'
  enum_name_re = r'(\w+)'
  optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?'
  enum_start_re = re.compile(r'^\s*enum\s+' + optional_class_or_struct_re +
      '\s*' + enum_name_re + '\s*' + optional_fixed_type_re + '\s*{\s*$')

  def __init__(self, lines, path=None):
    self._lines = lines
    self._path = path
    self._enum_definitions = []
    self._in_enum = False
    self._current_definition = None
    self._generator_directives = DirectiveSet()
    self._multi_line_generator_directive = None

  def _ApplyGeneratorDirectives(self):
    self._generator_directives.UpdateDefinition(self._current_definition)
    self._generator_directives = DirectiveSet()

  def ParseDefinitions(self):
    for line in self._lines:
      self._ParseLine(line)
    return self._enum_definitions

  def _ParseLine(self, line):
    if self._multi_line_generator_directive:
      self._ParseMultiLineDirectiveLine(line)
    elif not self._in_enum:
      self._ParseRegularLine(line)
    else:
      self._ParseEnumLine(line)

  def _ParseEnumLine(self, line):
    if HeaderParser.single_line_comment_re.match(line):
      return
    if HeaderParser.multi_line_comment_start_re.match(line):
      raise Exception('Multi-line comments in enums are not supported in ' +
                      self._path)
    enum_end = HeaderParser.enum_end_re.match(line)
    enum_entry = HeaderParser.enum_line_re.match(line)
    if enum_end:
      self._ApplyGeneratorDirectives()
      self._current_definition.Finalize()
      self._enum_definitions.append(self._current_definition)
      self._in_enum = False
    elif enum_entry:
      enum_key = enum_entry.groups()[0]
      enum_value = enum_entry.groups()[2]
      self._current_definition.AppendEntry(enum_key, enum_value)

  def _ParseMultiLineDirectiveLine(self, line):
    multi_line_directive_continuation = (
        HeaderParser.multi_line_directive_continuation_re.match(line))
    multi_line_directive_end = (
        HeaderParser.multi_line_directive_end_re.match(line))

    if multi_line_directive_continuation:
      value_cont = multi_line_directive_continuation.groups()[0]
      self._multi_line_generator_directive[1].append(value_cont)
    elif multi_line_directive_end:
      directive_name = self._multi_line_generator_directive[0]
      directive_value = "".join(self._multi_line_generator_directive[1])
      directive_value += multi_line_directive_end.groups()[0]
      self._multi_line_generator_directive = None
      self._generator_directives.Update(directive_name, directive_value)
    else:
      raise Exception('Malformed multi-line directive declaration in ' +
                      self._path)

  def _ParseRegularLine(self, line):
    enum_start = HeaderParser.enum_start_re.match(line)
    generator_directive = HeaderParser.generator_directive_re.match(line)
    multi_line_generator_directive_start = (
        HeaderParser.multi_line_generator_directive_start_re.match(line))

    if generator_directive:
      directive_name = generator_directive.groups()[0]
      directive_value = generator_directive.groups()[1]
      self._generator_directives.Update(directive_name, directive_value)
    elif multi_line_generator_directive_start:
      directive_name = multi_line_generator_directive_start.groups()[0]
      directive_value = multi_line_generator_directive_start.groups()[1]
      self._multi_line_generator_directive = (directive_name, [directive_value])
    elif enum_start:
      if self._generator_directives.empty:
        return
      self._current_definition = EnumDefinition(
          original_enum_name=enum_start.groups()[1],
          fixed_type=enum_start.groups()[3])
      self._in_enum = True

def GetScriptName():
  script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
  build_index = script_components.index('build')
  return os.sep.join(script_components[build_index:])


def DoGenerate(output_dir, source_paths, print_output_only=False):
  output_paths = []
  for source_path in source_paths:
    enum_definitions = DoParseHeaderFile(source_path)
    if not enum_definitions:
      raise Exception('No enums found in %s\n'
                      'Did you forget prefixing enums with '
                      '"// GENERATED_JAVA_ENUM_PACKAGE: foo"?' %
                      source_path)
    for enum_definition in enum_definitions:
      package_path = enum_definition.enum_package.replace('.', os.path.sep)
      file_name = enum_definition.class_name + '.java'
      output_path = os.path.join(output_dir, package_path, file_name)
      output_paths.append(output_path)
      if not print_output_only:
        build_utils.MakeDirectory(os.path.dirname(output_path))
        DoWriteOutput(source_path, output_path, enum_definition)
  return output_paths


def DoParseHeaderFile(path):
  with open(path) as f:
    return HeaderParser(f.readlines(), path).ParseDefinitions()


def GenerateOutput(source_path, enum_definition):
  template = Template("""
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is autogenerated by
//     ${SCRIPT_NAME}
// From
//     ${SOURCE_PATH}

package ${PACKAGE};

public class ${CLASS_NAME} {
${ENUM_ENTRIES}
}
""")

  enum_template = Template('  public static final int ${NAME} = ${VALUE};')
  enum_entries_string = []
  for enum_name, enum_value in enum_definition.entries.iteritems():
    values = {
        'NAME': enum_name,
        'VALUE': enum_value,
    }
    enum_entries_string.append(enum_template.substitute(values))
  enum_entries_string = '\n'.join(enum_entries_string)

  values = {
      'CLASS_NAME': enum_definition.class_name,
      'ENUM_ENTRIES': enum_entries_string,
      'PACKAGE': enum_definition.enum_package,
      'SCRIPT_NAME': GetScriptName(),
      'SOURCE_PATH': source_path,
  }
  return template.substitute(values)


def DoWriteOutput(source_path, output_path, enum_definition):
  with open(output_path, 'w') as out_file:
    out_file.write(GenerateOutput(source_path, enum_definition))

def AssertFilesList(output_paths, assert_files_list):
  actual = set(output_paths)
  expected = set(assert_files_list)
  if not actual == expected:
    need_to_add = list(actual - expected)
    need_to_remove = list(expected - actual)
    raise Exception('Output files list does not match expectations. Please '
                    'add %s and remove %s.' % (need_to_add, need_to_remove))

def DoMain(argv):
  usage = 'usage: %prog [options] output_dir input_file(s)...'
  parser = optparse.OptionParser(usage=usage)

  parser.add_option('--assert_file', action="append", default=[],
                    dest="assert_files_list", help='Assert that the given '
                    'file is an output. There can be multiple occurrences of '
                    'this flag.')
  parser.add_option('--print_output_only', help='Only print output paths.',
                    action='store_true')
  parser.add_option('--verbose', help='Print more information.',
                    action='store_true')

  options, args = parser.parse_args(argv)
  if len(args) < 2:
    parser.error('Need to specify output directory and at least one input file')
  output_paths = DoGenerate(args[0], args[1:],
                            print_output_only=options.print_output_only)

  if options.assert_files_list:
    AssertFilesList(output_paths, options.assert_files_list)

  if options.verbose:
    print 'Output paths:'
    print '\n'.join(output_paths)

  return ' '.join(output_paths)

if __name__ == '__main__':
  DoMain(sys.argv[1:])
