#!/usr/bin/env python
# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
 Converts a given ASCII proto into a binary resource.

"""
from __future__ import print_function
import abc
from importlib import util as imp_util
import optparse
import os
import re
import subprocess
import sys
import traceback


class GoogleProtobufModuleImporter:
  """A custom module importer for importing google.protobuf.

  See PEP #302 (https://www.python.org/dev/peps/pep-0302/) for full information
  on the Importer Protocol.
  """

  def __init__(self, paths):
    """Creates a loader that searches |paths| for google.protobuf modules."""
    self._paths = paths

  def _fullname_to_filepath(self, fullname):
    """Converts a full module name to a corresponding path to a .py file.

    e.g. google.protobuf.text_format -> pyproto/google/protobuf/text_format.py
    """
    for path in self._paths:
      filepath = os.path.join(path, fullname.replace('.', os.sep) + '.py')
      if os.path.isfile(filepath):
        return filepath
    return None

  def _module_exists(self, fullname):
    return self._fullname_to_filepath(fullname) is not None

  def find_module(self, fullname, path=None):
    """Returns a loader module for the google.protobuf module in pyproto."""
    if (fullname.startswith('google.protobuf.')
        and self._module_exists(fullname)):
      # Per PEP #302, this will result in self.load_module getting used
      # to load |fullname|.
      return self

    # Per PEP #302, if the module cannot be loaded, then return None.
    return None

  def load_module(self, fullname):
    """Loads the module specified by |fullname| and returns the module."""
    if fullname in sys.modules:
      # Per PEP #302, if |fullname| is in sys.modules, it must be returned.
      return sys.modules[fullname]

    if (not fullname.startswith('google.protobuf.') or
        not self._module_exists(fullname)):
      # Per PEP #302, raise ImportError if the requested module/package
      # cannot be loaded. This should never get reached for this simple loader,
      # but is included for completeness.
      raise ImportError(fullname)

    filepath = self._fullname_to_filepath(fullname)
    spec = imp_util.spec_from_file_location(fullname, filepath)
    loaded = imp_util.module_from_spec(spec)
    spec.loader.exec_module(loaded)

    return loaded

class BinaryProtoGenerator:

  # If the script is run in a virtualenv
  # (https://virtualenv.pypa.io/en/stable/), then no google.protobuf library
  # should be brought in from site-packages. Passing -S into the interpreter in
  # a virtualenv actually destroys the ability to import standard library
  # functions like optparse, so this script should not be wrapped if we're in a
  # virtualenv.
  def _IsInVirtualEnv(self):
    # This is the way used by pip and other software to detect virtualenv.
    return hasattr(sys, 'real_prefix')

  def _ImportProtoModules(self, paths):
    """Import the protobuf modules we need. |paths| is list of import paths"""
    for path in paths:
      # Put the path to our proto libraries in front, so that we don't use
      # system protobuf.
      sys.path.insert(1, path)

    if self._IsInVirtualEnv():
      # Add a custom module loader. When run in a virtualenv that has
      # google.protobuf installed, the site-package was getting searched first
      # despite that pyproto/ is at the start of the sys.path. The module
      # loaders in the meta_path precede all other imports (including even
      # builtins), which allows the proper google.protobuf from pyproto to be
      # found.
      sys.meta_path.append(GoogleProtobufModuleImporter(paths))

    import google.protobuf.text_format as text_format
    globals()['text_format'] = text_format
    self.ImportProtoModule()

  def _GenerateBinaryProtos(self, opts):
    """ Read the ASCII proto and generate one or more binary protos. """
    # Read the ASCII
    with open(opts.infile, 'r') as ifile:
      ascii_pb_str = ifile.read()

    # Parse it into a structured PB
    full_pb = self.EmptyProtoInstance()
    text_format.Merge(ascii_pb_str, full_pb)

    self.ValidatePb(opts, full_pb);
    self.ProcessPb(opts, full_pb)

  @abc.abstractmethod
  def ImportProtoModule(self):
    """ Import the proto module to be used by the generator. """
    pass

  @abc.abstractmethod
  def EmptyProtoInstance(self):
    """ Returns an empty proto instance to be filled by the generator."""
    pass

  @abc.abstractmethod
  def ValidatePb(self, opts, pb):
    """ Validate the basic values of the protobuf.  The
        file_type_policies_unittest.cc will also validate it by platform,
        but this will catch errors earlier.
    """
    pass

  @abc.abstractmethod
  def ProcessPb(self, opts, pb):
    """ Process the parsed prototobuf. """
    pass

  def AddCommandLineOptions(self, parser):
    """ Allows subclasses to add any options the command line parser. """
    pass

  def AddExtraCommandLineArgsForVirtualEnvRun(self, opts, command):
    """ Allows subclasses to add any extra command line arguments when running
        this under a virtualenv."""
    pass

  def VerifyArgs(self, opts):
    """ Allows subclasses to check command line parameters before running. """
    return True

  def Run(self):
    parser = optparse.OptionParser()
    # TODO(crbug.com/614082): Remove this once the bug is fixed.
    parser.add_option('-w', '--wrap', action="store_true", default=False,
                      help='Wrap this script in another python '
                      'execution to disable site-packages.  This is a '
                      'fix for http://crbug.com/605592')

    parser.add_option('-i', '--infile',
                      help='The ASCII proto file to read.')
    parser.add_option('-d', '--outdir',
                      help='Directory underwhich binary file(s) will be ' +
                           'written')
    parser.add_option('-o', '--outbasename',
                      help='Basename of the binary file to write to.')
    parser.add_option('-p', '--path', action="append",
                      help='Repeat this as needed.  Directory(s) containing ' +
                      'the your_proto_definition_pb2.py and ' +
                      'google.protobuf.text_format modules')
    self.AddCommandLineOptions(parser)

    (opts, args) = parser.parse_args()
    if opts.infile is None or opts.outdir is None or opts.outbasename is None:
      parser.print_help()
      return 1

    if opts.wrap and not self._IsInVirtualEnv():
      # Run this script again with different args to the interpreter to suppress
      # the inclusion of libraries, like google.protobuf, from site-packages,
      # which is checked before sys.path when resolving imports. We want to
      # specifically import the libraries injected into the sys.path in
      # ImportProtoModules().
      command = [sys.executable, '-S', '-s', sys.argv[0]]
      command += ['-i', opts.infile]
      command += ['-d', opts.outdir]
      command += ['-o', opts.outbasename]
      for path in opts.path:
        command += ['-p', path]

      self.AddExtraCommandLineArgsForVirtualEnvRun(opts, command);
      sys.exit(subprocess.call(command))

    self._ImportProtoModules(opts.path)

    if not self.VerifyArgs(opts):
      print("Wrong arguments")
      return 1

    try:
      self._GenerateBinaryProtos(opts)
    except Exception as e:
      print("ERROR: Failed to render binary version of %s:\n  %s\n%s" %
            (opts.infile, str(e), traceback.format_exc()))
      return 1
