# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Compile the Build API's proto.

Install proto using CIPD to ensure a consistent protoc version.
"""

from __future__ import print_function

import os

from chromite.lib import commandline
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import osutils

_API_DIR = os.path.join(constants.CHROMITE_DIR, 'api')
_CIPD_ROOT = os.path.join(constants.CHROMITE_DIR, '.cipd_bin')
_PROTOC = os.path.join(_CIPD_ROOT, 'protoc')
_PROTO_DIR = os.path.join(constants.CHROMITE_DIR, 'infra', 'proto')

PROTOC_VERSION = '3.6.1'


def _InstallProtoc():
  """Install protoc from CIPD."""
  cmd = ['cipd', 'ensure']
  # Clean up the output.
  cmd.extend(['-log-level', 'warning'])
  # Set the install location.
  cmd.extend(['-root', _CIPD_ROOT])

  ensure_content = ('infra/tools/protoc/${platform} '
                    'protobuf_version:v%s' % PROTOC_VERSION)
  with osutils.TempDir() as tempdir:
    ensure_file = os.path.join(tempdir, 'cipd_ensure_file')
    osutils.WriteFile(ensure_file, ensure_content)

    cmd.extend(['-ensure-file', ensure_file])

    cros_build_lib.RunCommand(cmd, cwd=constants.CHROMITE_DIR)

def _CleanTargetDirectory(directory):
  """Remove any existing generated files in the directory.

  This clean only removes the generated files to avoid accidentally destroying
  __init__.py customizations down the line. That will leave otherwise empty
  directories in place if things get moved. Neither case is relevant at the
  time of writing, but lingering empty directories seemed better than
  diagnosing accidental __init__.py changes.

  Args:
    directory (str): Path to be cleaned up.
  """
  for dirpath, _dirnames, filenames in os.walk(directory):
    old = [os.path.join(dirpath, f) for f in filenames if f.endswith('_pb2.py')]
    for current in old:
      osutils.SafeUnlink(current)

def _GenerateFiles(source, output):
  """Generate the proto files from the |source| tree into |output|.

  Args:
    source (str): Path to the proto source root directory.
    output (str): Path to the output root directory.
  """
  targets = []

  # Only compile the subset we need for the API.
  subdirs = [os.path.join(source, 'chromite'),
             os.path.join(source, 'chromiumos'),
             os.path.join(source, 'test_platform')]
  for basedir in subdirs:
    for dirpath, _dirnames, filenames in os.walk(basedir):
      for filename in filenames:
        if filename.endswith('.proto'):
          # We have a match, add the file.
          targets.append(os.path.join(dirpath, filename))

  template = ('%(protoc)s --python_out %(output)s '
              '--proto_path %(src)s  %(targets)s')
  cmd = template % {'protoc': _PROTOC, 'output': output, 'src': source,
                    'targets': ' '.join(targets)}
  cros_build_lib.RunCommand(cmd, shell=True, cwd=source)


def _InstallMissingInits(directory):
  """Add any __init__.py files not present in the generated protobuf folders."""
  for dirpath, _dirnames, filenames in os.walk(directory):
    if '__init__.py' not in filenames:
      osutils.Touch(os.path.join(dirpath, '__init__.py'))


def _PostprocessFiles(directory):
  """Do postprocessing on the generated files.

  Args:
    directory (str): The root directory containing the generated files that are
      to be processed.
  """
  # We are using a negative address here (the /address/! portion of the sed
  # command) to make sure we don't change any imports from protobuf itself.
  address = '^from google.protobuf'
  # Find: 'from x import y_pb2 as x_dot_y_pb2'.
  # "\(^google.protobuf[^ ]*\)" matches the module we're importing from.
  #   - \( and \) are for groups in sed.
  #   - ^google.protobuf prevents changing the import for protobuf's files.
  #   - [^ ] = Not a space. The [:space:] character set is too broad, but would
  #       technically work too.
  find = r'^from \([^ ]*\) import \([^ ]*\)_pb2 as \([^ ]*\)$'
  # Substitute: 'from chromite.api.gen.x import y_pb2 as x_dot_y_pb2'.
  sub = 'from chromite.api.gen.\\1 import \\2_pb2 as \\3'
  from_sed = ['sed', '-i', '/%(address)s/!s/%(find)s/%(sub)s/g' %
              {'address': address, 'find': find, 'sub': sub}]

  for dirpath, _dirnames, filenames in os.walk(directory):
    # Update the
    pb2 = [os.path.join(dirpath, f) for f in filenames if f.endswith('_pb2.py')]
    if pb2:
      cmd = from_sed + pb2
      cros_build_lib.RunCommand(cmd)


def CompileProto(output=None):
  """Compile the Build API protobuf files.

  By default this will compile from infra/proto/src to api/gen. The output
  directory may be changed, but the imports will always be treated as if it is
  in the default location.

  Args:
    output (str|None): The output directory.
  """
  source = os.path.join(_PROTO_DIR, 'src')
  output = output or os.path.join(_API_DIR, 'gen')

  _InstallProtoc()
  _CleanTargetDirectory(output)
  _GenerateFiles(source, output)
  _InstallMissingInits(output)
  _PostprocessFiles(output)


def GetParser():
  """Build the argument parser."""
  parser = commandline.ArgumentParser(description=__doc__)
  parser.add_argument('--destination', type='path',
                      help='The directory where the proto should be generated.'
                           'Defaults to the correct directory for the API.')
  return parser


def _ParseArguments(argv):
  """Parse and validate arguments."""
  parser = GetParser()
  opts = parser.parse_args(argv)

  opts.Freeze()
  return opts


def main(argv):
  opts = _ParseArguments(argv)

  CompileProto(output=opts.destination)
