#!/usr/bin/env python
# Copyright 2015 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 script accepts the output of version 2 of the mojom parser and uses that
# data to invoke the code generators.

import argparse
import imp
import os
import sys


def _ParseCLIArgs():
  """Parses the command line arguments.

  Returns:
    tuple<Namespace, list<str>> The first value of the tuple is a Namespace
    holding the value of the optional args. The second value of the tuple is
    a list of the remaining arguments.
  """
  parser = argparse.ArgumentParser(
      description='Generate bindings from mojom parser output.')
  parser.add_argument('filenames', nargs='*',
                      help='Filter on the set of .mojom files for which code '
                      'will be generated.')
  parser.add_argument('-f', '--file-graph', dest='file_graph',
                      help='Location of the parser output. "-" for stdin. '
                      '(default "-")', default='-')
  parser.add_argument("-o", "--output-dir", dest="output_dir", default=".",
                      help="output directory for generated files")
  parser.add_argument("-g", "--generators", dest="generators_string",
                      metavar="GENERATORS",
                      default="c++,dart,go,javascript,java,python",
                      help="comma-separated list of generators")
  parser.add_argument("-s", "--src-root-path", dest="src_root_path",
                      default=".",
                      help="relative path to the root of the source tree.")
  parser.add_argument("--no-gen-imports", action="store_true",
                      help="Generate code only for the files that are "
                      "specified on the command line. By default, code "
                      "is generated for all specified files and their "
                      "transitive imports.")
  parser.add_argument("--generate-type-info", dest="generate_type_info",
                      action="store_true",
                      help="generate mojom type descriptors")
  parser.add_argument("--no-generate-type-info", dest="generate_type_info",
                      action="store_false",
                      help="do not generate mojom type descriptors")
  parser.set_defaults(generate_type_info=False)

  return parser.parse_known_args()

# We assume this script is located in the Mojo SDK in tools/bindings.
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
SDK_ROOT = os.path.abspath(os.path.join(THIS_DIR, os.pardir, os.pardir))
PYTHON_SDK_DIR = os.path.abspath(os.path.join(SDK_ROOT, "python"))

sys.path.insert(0, PYTHON_SDK_DIR)
# In order to use mojom_files_mojom we need to make sure the dummy mojo_system
# can be found on the python path.
sys.path.insert(0, os.path.join(PYTHON_SDK_DIR, "dummy_mojo_system"))

sys.path.insert(0, os.path.join(THIS_DIR, "pylib"))


from mojom.generate.generated import mojom_files_mojom
from mojom.generate import mojom_translator
from mojo_bindings import serialization


def LoadGenerators(generators_string):
  if not generators_string:
    return []  # No generators.

  generators_dir = os.path.join(THIS_DIR, "generators")
  generators = []
  for generator_name in [s.strip() for s in generators_string.split(",")]:
    generator_name_lower = generator_name.lower()
    # "Built-in" generators:
    if generator_name_lower == "c++":
      generator_py_name = os.path.join(generators_dir,
        "mojom_cpp_generator.py")
    elif generator_name_lower == "dart":
      generator_py_name = os.path.join(generators_dir,
        "mojom_dart_generator.py")
    elif generator_name_lower == "go":
      generator_py_name = os.path.join(generators_dir,
        "mojom_go_generator.py")
    elif generator_name_lower == "javascript":
      generator_py_name = os.path.join(generators_dir,
        "mojom_js_generator.py")
    elif generator_name_lower == "java":
      generator_py_name = os.path.join(generators_dir,
        "mojom_java_generator.py")
    elif generator_name_lower == "python":
      generator_py_name = os.path.join(generators_dir,
        "mojom_python_generator.py")
    # Specified generator python module:
    elif generator_name.endswith(".py"):
      generator_py_name = generator_name
    else:
      print "Unknown generator name %s" % generator_name
      sys.exit(1)
    generator_module = imp.load_source(os.path.basename(generator_py_name)[:-3],
                                       generator_py_name)
    generators.append(generator_module)
  return generators


def ReadMojomFileGraphFromFile(fp):
  """Reads a mojom_files_mojom.MojomFileGraph from a file.

  Args:
    fp: A file pointer from which a serialized mojom_fileS_mojom.MojomFileGraph
        can be read.

  Returns:
    The mojom_files_mojom.MojomFileGraph that was deserialized from the file.
  """
  data = bytearray(fp.read())
  context = serialization.RootDeserializationContext(data, [])
  return mojom_files_mojom.MojomFileGraph.Deserialize(context)


def FixModulePath(module, abs_src_root_path):
  """Fix the path attribute of the provided module and its imports.

  The path provided for the various modules is the absolute path to the mojom
  file which the module represents. But the generators expect the path to be
  relative to the root of the source tree.

  Args:
    module: {module.Module} whose path is to be updated.
    abs_src_root_path: {str} absolute path to the root of the source tree.
  """
  module.path = os.path.relpath(module.path, abs_src_root_path)
  if not hasattr(module, 'imports'):
    return
  for import_dict in module.imports:
    FixModulePath(import_dict['module'], abs_src_root_path)


def main():
  args, remaining_args = _ParseCLIArgs()

  if args.file_graph == '-':
    fp = sys.stdin
  else:
    fp = open(args.file_graph)

  mojom_file_graph = ReadMojomFileGraphFromFile(fp)
  mojom_modules = mojom_translator.TranslateFileGraph(mojom_file_graph)

  # Note that we are using the word "module" in two unrelated ways here.
  # A mojom module is the Python data structure defined in module.py that
  # represents a Mojom file (sometimes referred to as a Mojom module.)
  # A generator module is a Python module in the sense of the entity the Python
  # runtime loads corresponding to a .py file.
  generator_modules = LoadGenerators(args.generators_string)

  abs_src_root_path = os.path.abspath(args.src_root_path)
  for _, mojom_module in mojom_modules.iteritems():
    # If --no-gen-imports is specified then skip the code generation step for
    # any modules that do not have the |specified_name| field set. This field
    # being set indicates that the module was translated from a .mojom file
    # whose name was explicitly requested during parsing. Otherwise the module
    # is included only becuase of a mojom import statement.
    if args.no_gen_imports and not mojom_module.specified_name:
      continue
    FixModulePath(mojom_module, abs_src_root_path)
    for generator_module in generator_modules:
      generator = generator_module.Generator(mojom_module, args.output_dir)

      # Look at unparsed args for generator-specific args.
      filtered_args = []
      if hasattr(generator_module, 'GENERATOR_PREFIX'):
        prefix = '--' + generator_module.GENERATOR_PREFIX + '_'
        filtered_args = [arg for arg in remaining_args
                         if arg.startswith(prefix)]
      if args.generate_type_info:
        filtered_args.append("--generate_type_info")

      generator.GenerateFiles(filtered_args)


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