#! /usr/bin/python
#
# Protocol Buffers - Google's data interchange format
# Copyright 2015 Google Inc.  All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""PDDM - Poor Developers' Debug-able Macros

A simple markup that can be added in comments of source so they can then be
expanded out into code. Most of this could be done with CPP macros, but then
developers can't really step through them in the debugger, this way they are
expanded to the same code, but you can debug them.

Any file can be processed, but the syntax is designed around a C based compiler.
Processed lines start with "//%".  There are three types of sections you can
create: Text (left alone), Macro Definitions, and Macro Expansions.  There is
no order required between definitions and expansions, all definitions are read
before any expansions are processed (thus, if desired, definitions can be put
at the end of the file to keep them out of the way of the code).

Macro Definitions are started with "//%PDDM-DEFINE Name(args)" and all lines
afterwards that start with "//%" are included in the definition.  Multiple
macros can be defined in one block by just using a another "//%PDDM-DEFINE"
line to start the next macro.  Optionally, a macro can be ended with
"//%PDDM-DEFINE-END", this can be useful when you want to make it clear that
trailing blank lines are included in the macro.  You can also end a definition
with an expansion.

Macro Expansions are started by single lines containing
"//%PDDM-EXPAND Name(args)" and then with "//%PDDM-EXPAND-END" or another
expansions.  All lines in-between are replaced by the result of the expansion.
The first line of the expansion is always a blank like just for readability.

Expansion itself is pretty simple, one macro can invoke another macro, but
you cannot nest the invoke of a macro in another macro (i.e. - can't do
"foo(bar(a))", but you can define foo(a) and bar(b) where bar invokes foo()
within its expansion.

When macros are expanded, the arg references can also add "$O" suffix to the
name (i.e. - "NAME$O") to specify an option to be applied. The options are:

    $S - Replace each character in the value with a space.
    $l - Lowercase the first letter of the value.
    $L - Lowercase the whole value.
    $u - Uppercase the first letter of the value.
    $U - Uppercase the whole value.

Within a macro you can use ## to cause things to get joined together after
expansion (i.e. - "a##b" within a macro will become "ab").

Example:

    int foo(MyEnum x) {
    switch (x) {
    //%PDDM-EXPAND case(Enum_Left, 1)
    //%PDDM-EXPAND case(Enum_Center, 2)
    //%PDDM-EXPAND case(Enum_Right, 3)
    //%PDDM-EXPAND-END
    }

    //%PDDM-DEFINE case(_A, _B)
    //%  case _A:
    //%    return _B;

  A macro ends at the start of the next one, or an optional %PDDM-DEFINE-END
  can be used to avoid adding extra blank lines/returns (or make it clear when
  it is desired).

  One macro can invoke another by simply using its name NAME(ARGS). You cannot
  nest an invoke inside another (i.e. - NAME1(NAME2(ARGS)) isn't supported).

  Within a macro you can use ## to cause things to get joined together after
  processing (i.e. - "a##b" within a macro will become "ab").


"""

import optparse
import os
import re
import sys


# Regex for macro definition.
_MACRO_RE = re.compile(r'(?P<name>\w+)\((?P<args>.*?)\)')
# Regex for macro's argument definition.
_MACRO_ARG_NAME_RE = re.compile(r'^\w+$')

# Line inserted after each EXPAND.
_GENERATED_CODE_LINE = (
  '// This block of code is generated, do not edit it directly.'
)


def _MacroRefRe(macro_names):
  # Takes in a list of macro names and makes a regex that will match invokes
  # of those macros.
  return re.compile(r'\b(?P<macro_ref>(?P<name>(%s))\((?P<args>.*?)\))' %
                    '|'.join(macro_names))

def _MacroArgRefRe(macro_arg_names):
  # Takes in a list of macro arg names and makes a regex that will match
  # uses of those args.
  return re.compile(r'\b(?P<name>(%s))(\$(?P<option>.))?\b' %
                    '|'.join(macro_arg_names))


class PDDMError(Exception):
  """Error thrown by pddm."""
  pass


class MacroCollection(object):
  """Hold a set of macros and can resolve/expand them."""

  def __init__(self, a_file=None):
    """Initializes the collection.

    Args:
      a_file: The file like stream to parse.

    Raises:
      PDDMError if there are any issues.
    """
    self._macros = dict()
    if a_file:
      self.ParseInput(a_file)

  class MacroDefinition(object):
    """Holds a macro definition."""

    def __init__(self, name, arg_names):
      self._name = name
      self._args = tuple(arg_names)
      self._body = ''
      self._needNewLine = False

    def AppendLine(self, line):
      if self._needNewLine:
        self._body += '\n'
      self._body += line
      self._needNewLine = not line.endswith('\n')

    @property
    def name(self):
      return self._name

    @property
    def args(self):
      return self._args

    @property
    def body(self):
      return self._body

  def ParseInput(self, a_file):
    """Consumes input extracting definitions.

    Args:
      a_file: The file like stream to parse.

    Raises:
      PDDMError if there are any issues.
    """
    input_lines = a_file.read().splitlines()
    self.ParseLines(input_lines)

  def ParseLines(self, input_lines):
    """Parses list of lines.

    Args:
      input_lines: A list of strings of input to parse (no newlines on the
                   strings).

    Raises:
      PDDMError if there are any issues.
    """
    current_macro = None
    for line in input_lines:
      if line.startswith('PDDM-'):
        directive = line.split(' ', 1)[0]
        if directive == 'PDDM-DEFINE':
          name, args = self._ParseDefineLine(line)
          if self._macros.get(name):
            raise PDDMError('Attempt to redefine macro: "%s"' % line)
          current_macro = self.MacroDefinition(name, args)
          self._macros[name] = current_macro
          continue
        if directive == 'PDDM-DEFINE-END':
          if not current_macro:
            raise PDDMError('Got DEFINE-END directive without an active macro:'
                            ' "%s"' % line)
          current_macro = None
          continue
        raise PDDMError('Hit a line with an unknown directive: "%s"' % line)

      if current_macro:
        current_macro.AppendLine(line)
        continue

      # Allow blank lines between macro definitions.
      if line.strip() == '':
        continue

      raise PDDMError('Hit a line that wasn\'t a directive and no open macro'
                      ' definition: "%s"' % line)

  def _ParseDefineLine(self, input_line):
    assert input_line.startswith('PDDM-DEFINE')
    line = input_line[12:].strip()
    match = _MACRO_RE.match(line)
    # Must match full line
    if match is None or match.group(0) != line:
      raise PDDMError('Failed to parse macro definition: "%s"' % input_line)
    name = match.group('name')
    args_str = match.group('args').strip()
    args = []
    if args_str:
      for part in args_str.split(','):
        arg = part.strip()
        if arg == '':
          raise PDDMError('Empty arg name in macro definition: "%s"'
                          % input_line)
        if not _MACRO_ARG_NAME_RE.match(arg):
          raise PDDMError('Invalid arg name "%s" in macro definition: "%s"'
                          % (arg, input_line))
        if arg in args:
          raise PDDMError('Arg name "%s" used more than once in macro'
                          ' definition: "%s"' % (arg, input_line))
        args.append(arg)
    return (name, tuple(args))

  def Expand(self, macro_ref_str):
    """Expands the macro reference.

    Args:
      macro_ref_str: String of a macro reference (i.e. foo(a, b)).

    Returns:
      The text from the expansion.

    Raises:
      PDDMError if there are any issues.
    """
    match = _MACRO_RE.match(macro_ref_str)
    if match is None or match.group(0) != macro_ref_str:
      raise PDDMError('Failed to parse macro reference: "%s"' % macro_ref_str)
    if match.group('name') not in self._macros:
      raise PDDMError('No macro named "%s".' % match.group('name'))
    return self._Expand(match, [], macro_ref_str)

  def _FormatStack(self, macro_ref_stack):
    result = ''
    for _, macro_ref in reversed(macro_ref_stack):
      result += '\n...while expanding "%s".' % macro_ref
    return result

  def _Expand(self, macro_ref_match, macro_stack, macro_ref_str=None):
    if macro_ref_str is None:
      macro_ref_str = macro_ref_match.group('macro_ref')
    name = macro_ref_match.group('name')
    for prev_name, prev_macro_ref in macro_stack:
      if name == prev_name:
        raise PDDMError('Found macro recusion, invoking "%s":%s' %
                        (macro_ref_str, self._FormatStack(macro_stack)))
    macro = self._macros[name]
    args_str = macro_ref_match.group('args').strip()
    args = []
    if args_str or len(macro.args):
      args = [x.strip() for x in args_str.split(',')]
    if len(args) != len(macro.args):
      raise PDDMError('Expected %d args, got: "%s".%s' %
                      (len(macro.args), macro_ref_str,
                       self._FormatStack(macro_stack)))
    # Replace args usages.
    result = self._ReplaceArgValues(macro, args, macro_ref_str, macro_stack)
    # Expand any macro invokes.
    new_macro_stack = macro_stack + [(name, macro_ref_str)]
    while True:
      eval_result = self._EvalMacrosRefs(result, new_macro_stack)
      # Consume all ## directives to glue things together.
      eval_result = eval_result.replace('##', '')
      if eval_result == result:
        break
      result = eval_result
    return result

  def _ReplaceArgValues(self,
                        macro, arg_values, macro_ref_to_report, macro_stack):
    if len(arg_values) == 0:
      # Nothing to do
      return macro.body
    assert len(arg_values) == len(macro.args)
    args = dict(zip(macro.args, arg_values))
    def _lookupArg(match):
      val = args[match.group('name')]
      opt = match.group('option')
      if opt:
        if opt == 'S': # Spaces for the length
          return ' ' * len(val)
        elif opt == 'l': # Lowercase first character
          if val:
            return val[0].lower() + val[1:]
          else:
            return val
        elif opt == 'L': # All Lowercase
          return val.lower()
        elif opt == 'u': # Uppercase first character
          if val:
            return val[0].upper() + val[1:]
          else:
            return val
        elif opt == 'U': # All Uppercase
          return val.upper()
        else:
          raise PDDMError('Unknown arg option "%s$%s" while expanding "%s".%s'
                          % (match.group('name'), match.group('option'),
                             macro_ref_to_report,
                             self._FormatStack(macro_stack)))
      return val
    # Let the regex do the work!
    macro_arg_ref_re = _MacroArgRefRe(macro.args)
    return macro_arg_ref_re.sub(_lookupArg, macro.body)

  def _EvalMacrosRefs(self, text, macro_stack):
    macro_ref_re = _MacroRefRe(self._macros.keys())
    def _resolveMacro(match):
      return self._Expand(match, macro_stack)
    return macro_ref_re.sub(_resolveMacro, text)


class SourceFile(object):
  """Represents a source file with PDDM directives in it."""

  def __init__(self, a_file, import_resolver=None):
    """Initializes the file reading in the file.

    Args:
      a_file: The file to read in.
      import_resolver: a function that given a path will return a stream for
        the contents.

    Raises:
      PDDMError if there are any issues.
    """
    self._sections = []
    self._original_content = a_file.read()
    self._import_resolver = import_resolver
    self._processed_content = None

  class SectionBase(object):

    def __init__(self, first_line_num):
      self._lines = []
      self._first_line_num = first_line_num

    def TryAppend(self, line, line_num):
      """Try appending a line.

      Args:
        line: The line to append.
        line_num: The number of the line.

      Returns:
        A tuple of (SUCCESS, CAN_ADD_MORE).  If SUCCESS if False, the line
        wasn't append.  If SUCCESS is True, then CAN_ADD_MORE is True/False to
        indicate if more lines can be added after this one.
      """
      assert False, "sublcass should have overridden"
      return (False, False)

    def HitEOF(self):
      """Called when the EOF was reached for for a given section."""
      pass

    def BindMacroCollection(self, macro_collection):
      """Binds the chunk to a macro collection.

      Args:
        macro_collection: The collection to bind too.
      """
      pass

    def Append(self, line):
      self._lines.append(line)

    @property
    def lines(self):
      return self._lines

    @property
    def num_lines_captured(self):
      return len(self._lines)

    @property
    def first_line_num(self):
      return self._first_line_num

    @property
    def first_line(self):
      if not self._lines:
        return ''
      return self._lines[0]

    @property
    def text(self):
      return '\n'.join(self.lines) + '\n'

  class TextSection(SectionBase):
    """Text section that is echoed out as is."""

    def TryAppend(self, line, line_num):
      if line.startswith('//%PDDM'):
        return (False, False)
      self.Append(line)
      return (True, True)

  class ExpansionSection(SectionBase):
    """Section that is the result of an macro expansion."""

    def __init__(self, first_line_num):
      SourceFile.SectionBase.__init__(self, first_line_num)
      self._macro_collection = None

    def TryAppend(self, line, line_num):
      if line.startswith('//%PDDM'):
        directive = line.split(' ', 1)[0]
        if directive == '//%PDDM-EXPAND':
          self.Append(line)
          return (True, True)
        if directive == '//%PDDM-EXPAND-END':
          assert self.num_lines_captured > 0
          return (True, False)
        raise PDDMError('Ran into directive ("%s", line %d) while in "%s".' %
                        (directive, line_num, self.first_line))
      # Eat other lines.
      return (True, True)

    def HitEOF(self):
      raise PDDMError('Hit the end of the file while in "%s".' %
                      self.first_line)

    def BindMacroCollection(self, macro_collection):
      self._macro_collection = macro_collection

    @property
    def lines(self):
      captured_lines = SourceFile.SectionBase.lines.fget(self)
      directive_len = len('//%PDDM-EXPAND')
      result = []
      for line in captured_lines:
        result.append(line)
        if self._macro_collection:
          # Always add a blank line, seems to read better. (If need be, add an
          # option to the EXPAND to indicate if this should be done.)
          result.extend([_GENERATED_CODE_LINE, ''])
          macro = line[directive_len:].strip()
          try:
            expand_result = self._macro_collection.Expand(macro)
            # Since expansions are line oriented, strip trailing whitespace
            # from the lines.
            lines = [x.rstrip() for x in expand_result.split('\n')]
            result.append('\n'.join(lines))
          except PDDMError as e:
            raise PDDMError('%s\n...while expanding "%s" from the section'
                            ' that started:\n   Line %d: %s' %
                            (e.message, macro,
                             self.first_line_num, self.first_line))

      # Add the ending marker.
      if len(captured_lines) == 1:
        result.append('//%%PDDM-EXPAND-END %s' %
                       captured_lines[0][directive_len:].strip())
      else:
        result.append('//%%PDDM-EXPAND-END (%s expansions)' % len(captured_lines))

      return result

  class DefinitionSection(SectionBase):
    """Section containing macro definitions"""

    def TryAppend(self, line, line_num):
      if not line.startswith('//%'):
        return (False, False)
      if line.startswith('//%PDDM'):
        directive = line.split(' ', 1)[0]
        if directive == "//%PDDM-EXPAND":
          return False, False
        if directive not in ('//%PDDM-DEFINE', '//%PDDM-DEFINE-END'):
          raise PDDMError('Ran into directive ("%s", line %d) while in "%s".' %
                          (directive, line_num, self.first_line))
      self.Append(line)
      return (True, True)

    def BindMacroCollection(self, macro_collection):
      if macro_collection:
        try:
          # Parse the lines after stripping the prefix.
          macro_collection.ParseLines([x[3:] for x in self.lines])
        except PDDMError as e:
          raise PDDMError('%s\n...while parsing section that started:\n'
                          '  Line %d: %s' %
                          (e.message, self.first_line_num, self.first_line))

  class ImportDefinesSection(SectionBase):
    """Section containing an import of PDDM-DEFINES from an external file."""

    def __init__(self, first_line_num, import_resolver):
      SourceFile.SectionBase.__init__(self, first_line_num)
      self._import_resolver = import_resolver

    def TryAppend(self, line, line_num):
      if not line.startswith('//%PDDM-IMPORT-DEFINES '):
        return (False, False)
      assert self.num_lines_captured == 0
      self.Append(line)
      return (True, False)

    def BindMacroCollection(self, macro_colletion):
      if not macro_colletion:
        return
      if self._import_resolver is None:
        raise PDDMError('Got an IMPORT-DEFINES without a resolver (line %d):'
                        ' "%s".' % (self.first_line_num, self.first_line))
      import_name = self.first_line.split(' ', 1)[1].strip()
      imported_file = self._import_resolver(import_name)
      if imported_file is None:
        raise PDDMError('Resolver failed to find "%s" (line %d):'
                        ' "%s".' %
                        (import_name, self.first_line_num, self.first_line))
      try:
        imported_src_file = SourceFile(imported_file, self._import_resolver)
        imported_src_file._ParseFile()
        for section in imported_src_file._sections:
          section.BindMacroCollection(macro_colletion)
      except PDDMError as e:
        raise PDDMError('%s\n...while importing defines:\n'
                        '  Line %d: %s' %
                        (e.message, self.first_line_num, self.first_line))

  def _ParseFile(self):
    self._sections = []
    lines = self._original_content.splitlines()
    cur_section = None
    for line_num, line in enumerate(lines, 1):
      if not cur_section:
        cur_section = self._MakeSection(line, line_num)
      was_added, accept_more = cur_section.TryAppend(line, line_num)
      if not was_added:
        cur_section = self._MakeSection(line, line_num)
        was_added, accept_more = cur_section.TryAppend(line, line_num)
        assert was_added
      if not accept_more:
        cur_section = None

    if cur_section:
      cur_section.HitEOF()

  def _MakeSection(self, line, line_num):
    if not line.startswith('//%PDDM'):
      section = self.TextSection(line_num)
    else:
      directive = line.split(' ', 1)[0]
      if directive == '//%PDDM-EXPAND':
        section = self.ExpansionSection(line_num)
      elif directive == '//%PDDM-DEFINE':
        section = self.DefinitionSection(line_num)
      elif directive == '//%PDDM-IMPORT-DEFINES':
        section = self.ImportDefinesSection(line_num, self._import_resolver)
      else:
        raise PDDMError('Unexpected line %d: "%s".' % (line_num, line))
    self._sections.append(section)
    return section

  def ProcessContent(self, strip_expansion=False):
    """Processes the file contents."""
    self._ParseFile()
    if strip_expansion:
      # Without a collection the expansions become blank, removing them.
      collection = None
    else:
      collection = MacroCollection()
    for section in self._sections:
      section.BindMacroCollection(collection)
    result = ''
    for section in self._sections:
      result += section.text
    self._processed_content = result

  @property
  def original_content(self):
    return self._original_content

  @property
  def processed_content(self):
    return self._processed_content


def main(args):
  usage = '%prog [OPTIONS] PATH ...'
  description = (
      'Processes PDDM directives in the given paths and write them back out.'
  )
  parser = optparse.OptionParser(usage=usage, description=description)
  parser.add_option('--dry-run',
                    default=False, action='store_true',
                    help='Don\'t write back to the file(s), just report if the'
                    ' contents needs an update and exit with a value of 1.')
  parser.add_option('--verbose',
                    default=False, action='store_true',
                    help='Reports is a file is already current.')
  parser.add_option('--collapse',
                    default=False, action='store_true',
                    help='Removes all the generated code.')
  opts, extra_args = parser.parse_args(args)

  if not extra_args:
    parser.error('Need atleast one file to process')

  result = 0
  for a_path in extra_args:
    if not os.path.exists(a_path):
      sys.stderr.write('ERROR: File not found: %s\n' % a_path)
      return 100

    def _ImportResolver(name):
      # resolve based on the file being read.
      a_dir = os.path.dirname(a_path)
      import_path = os.path.join(a_dir, name)
      if not os.path.exists(import_path):
        return None
      return open(import_path, 'r')

    with open(a_path, 'r') as f:
      src_file = SourceFile(f, _ImportResolver)

    try:
      src_file.ProcessContent(strip_expansion=opts.collapse)
    except PDDMError as e:
      sys.stderr.write('ERROR: %s\n...While processing "%s"\n' %
                       (e.message, a_path))
      return 101

    if src_file.processed_content != src_file.original_content:
      if not opts.dry_run:
        print 'Updating for "%s".' % a_path
        with open(a_path, 'w') as f:
          f.write(src_file.processed_content)
      else:
        # Special result to indicate things need updating.
        print 'Update needed for "%s".' % a_path
        result = 1
    elif opts.verbose:
      print 'No update for "%s".' % a_path

  return result


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