# 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.
# Deleted from Chromium in https://crrev.com/097f64c631.

"""Converts a given gypi file to a python scope and writes the result to stdout.

USING THIS SCRIPT IN CHROMIUM

Forking Python to run this script in the middle of GN is slow, especially on
Windows, and it makes both the GYP and GN files harder to follow. You can't
use "git grep" to find files in the GN build any more, and tracking everything
in GYP down requires a level of indirection. Any calls will have to be removed
and cleaned up once the GYP-to-GN transition is complete.

As a result, we only use this script when the list of files is large and
frequently-changing. In these cases, having one canonical list outweights the
downsides.

As of this writing, the GN build is basically complete. It's likely that all
large and frequently changing targets where this is appropriate use this
mechanism already. And since we hope to turn down the GYP build soon, the time
horizon is also relatively short. As a result, it is likely that no additional
uses of this script should every be added to the build. During this later part
of the transition period, we should be focusing more and more on the absolute
readability of the GN build.


HOW TO USE

It is assumed that the file contains a toplevel dictionary, and this script
will return that dictionary as a GN "scope" (see example below). This script
does not know anything about GYP and it will not expand variables or execute
conditions.

It will strip conditions blocks.

A variables block at the top level will be flattened so that the variables
appear in the root dictionary. This way they can be returned to the GN code.

Say your_file.gypi looked like this:
  {
     'sources': [ 'a.cc', 'b.cc' ],
     'defines': [ 'ENABLE_DOOM_MELON' ],
  }

You would call it like this:
  gypi_values = exec_script("//build/gypi_to_gn.py",
                            [ rebase_path("your_file.gypi") ],
                            "scope",
                            [ "your_file.gypi" ])

Notes:
 - The rebase_path call converts the gypi file from being relative to the
   current build file to being system absolute for calling the script, which
   will have a different current directory than this file.

 - The "scope" parameter tells GN to interpret the result as a series of GN
   variable assignments.

 - The last file argument to exec_script tells GN that the given file is a
   dependency of the build so Ninja can automatically re-run GN if the file
   changes.

Read the values into a target like this:
  component("mycomponent") {
    sources = gypi_values.sources
    defines = gypi_values.defines
  }

Sometimes your .gypi file will include paths relative to a different
directory than the current .gn file. In this case, you can rebase them to
be relative to the current directory.
  sources = rebase_path(gypi_values.sources, ".",
                        "//path/gypi/input/values/are/relative/to")

This script will tolerate a 'variables' in the toplevel dictionary or not. If
the toplevel dictionary just contains one item called 'variables', it will be
collapsed away and the result will be the contents of that dictinoary. Some
.gypi files are written with or without this, depending on how they expect to
be embedded into a .gyp file.

This script also has the ability to replace certain substrings in the input.
Generally this is used to emulate GYP variable expansion. If you passed the
argument "--replace=<(foo)=bar" then all instances of "<(foo)" in strings in
the input will be replaced with "bar":

  gypi_values = exec_script("//build/gypi_to_gn.py",
                            [ rebase_path("your_file.gypi"),
                              "--replace=<(foo)=bar"],
                            "scope",
                            [ "your_file.gypi" ])

"""

from __future__ import absolute_import
from __future__ import print_function
from optparse import OptionParser
import os
import sys

try:
  # May already be in the import path.
  import gn_helpers
except ImportError as e:
  # Add src/build to import path.
  cef_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
  src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir))
  sys.path.append(os.path.join(src_dir, 'build'))
  import gn_helpers


def LoadPythonDictionary(path):
  file_string = open(path).read()
  try:
    file_data = eval(file_string, {'__builtins__': None}, None)
  except SyntaxError as e:
    e.filename = path
    raise
  except Exception as e:
    raise Exception("Unexpected error while reading %s: %s" % (path, str(e)))

  assert isinstance(file_data, dict), "%s does not eval to a dictionary" % path

  # Flatten any variables to the top level.
  if 'variables' in file_data:
    file_data.update(file_data['variables'])
    del file_data['variables']

  # Strip all elements that this script can't process.
  elements_to_strip = [
    'conditions',
    'target_conditions',
    'target_defaults',
    'targets',
    'includes',
    'actions',
  ]
  for element in elements_to_strip:
    if element in file_data:
      del file_data[element]

  return file_data


def ReplaceSubstrings(values, search_for, replace_with):
  """Recursively replaces substrings in a value.

  Replaces all substrings of the "search_for" with "repace_with" for all
  strings occurring in "values". This is done by recursively iterating into
  lists as well as the keys and values of dictionaries."""
  if isinstance(values, str):
    return values.replace(search_for, replace_with)

  if isinstance(values, list):
    return [ReplaceSubstrings(v, search_for, replace_with) for v in values]

  if isinstance(values, dict):
    # For dictionaries, do the search for both the key and values.
    result = {}
    for key, value in values.items():
      new_key = ReplaceSubstrings(key, search_for, replace_with)
      new_value = ReplaceSubstrings(value, search_for, replace_with)
      result[new_key] = new_value
    return result

  # Assume everything else is unchanged.
  return values

def main():
  parser = OptionParser()
  parser.add_option("-r", "--replace", action="append",
    help="Replaces substrings. If passed a=b, replaces all substrs a with b.")
  (options, args) = parser.parse_args()

  if len(args) != 1:
    raise Exception("Need one argument which is the .gypi file to read.")

  data = LoadPythonDictionary(args[0])
  if options.replace:
    # Do replacements for all specified patterns.
    for replace in options.replace:
      split = replace.split('=')
      # Allow "foo=" to replace with nothing.
      if len(split) == 1:
        split.append('')
      assert len(split) == 2, "Replacement must be of the form 'key=value'."
      data = ReplaceSubstrings(data, split[0], split[1])

  # Sometimes .gypi files use the GYP syntax with percents at the end of the
  # variable name (to indicate not to overwrite a previously-defined value):
  #   'foo%': 'bar',
  # Convert these to regular variables.
  for key in data:
    if len(key) > 1 and key[len(key) - 1] == '%':
      data[key[:-1]] = data[key]
      del data[key]

  print(gn_helpers.ToGNString(data))

if __name__ == '__main__':
  try:
    main()
  except Exception as e:
    print(str(e))
    sys.exit(1)
