#!/usr/bin/env python
# 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.

# Modifications Copyright 2017 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tries to translate a GYP file into a GN file.

Output from this script should be piped to ``gn format --stdin``. It most likely
needs to be manually fixed after that as well.
"""

import argparse
import ast
import collections
import itertools
import os
import os.path
import re
import sys

sys.path.append(
    os.path.abspath(
        os.path.join(__file__, os.pardir, os.pardir, os.pardir)))
import cobalt.tools.paths  # pylint: disable=g-import-not-at-top

VariableRewrite = collections.namedtuple('VariableRewrite',
                                         ['name', 'value_rewrites'])

# The directory containing the input file, as a repository-absolute (//foo/bar)
# path
repo_abs_input_file_dir = ''
deps_substitutions = {}
variable_rewrites = {}


class GNException(Exception):
  pass


class GYPCondToGNNodeVisitor(ast.NodeVisitor):
  """An AST NodeVisitor which translates GYP conditions to GN strings.

  Given a GYP condition as an AST with mode eval, outputs a string containing
  the GN equivalent of that condition. Simplifies conditions involving the
  variables OS and os_posix, and performs variable substitutions.

  Example:
  (Assume arm_neon is renamed to arm_use_neon and converted from 0/1 to
  true/false):

  >>> g = GYPCondToGNNodeVisitor()
  >>> g.visit(ast.parse('arm_neon and target_arch=="xb1"', mode='eval'))
  '(arm_use_neon && target_cpu == "xb1")'
  >>> g.visit(ast.parse('use_system_libjpeg and target_arch=="xb1"',
  ...                   mode='eval'))
  '(use_system_libjpeg && target_cpu == "xb1")'
  >>> g.visit(ast.parse('arm_neon == 1', mode='eval'))
  'arm_use_neon == true'
  >>> g.visit(ast.parse('1', mode='eval'))
  'true'
  >>> g.visit(ast.parse('0', mode='eval'))
  'false'
  >>> g.visit(ast.parse('arm_neon != 0 and target_arch != "xb1" and
  use_system_libjpeg or enable_doom_melon', mode='eval'))
  '((arm_use_neon != false && target_cpu != "xb1" && use_system_libjpeg) ||
  enable_doom_melon)'
  >>> g.visit(ast.parse('arm_neon != 0 and target_arch != "xb1" or
  use_system_libjpeg and enable_doom_melon', mode='eval'))
  '((arm_use_neon != false && target_cpu != "xb1") || (use_system_libjpeg &&
  enable_doom_melon))'
  """

  def visit_Expression(self, expr):  # pylint: disable=invalid-name
    return self.visit(expr.body)

  def visit_Num(self, num):  # pylint: disable=invalid-name
    # A number that doesn't occur inside a Compare is taken in boolean context
    return GYPValueToGNString(bool(num.n))

  def visit_Str(self, string):  # pylint: disable=invalid-name
    return GYPValueToGNString(string.s)

  def visit_Name(self, name):  # pylint: disable=invalid-name
    if name.id in variable_rewrites:
      return variable_rewrites[name.id].name
    else:
      return name.id

  def visit_BoolOp(self, boolop):  # pylint: disable=invalid-name
    glue = ' && ' if isinstance(boolop.op, ast.And) else ' || '
    return '(' + glue.join(itertools.imap(self.visit, boolop.values)) + ')'

  def visit_Compare(self, compare):  # pylint: disable=invalid-name
    if len(compare.ops) != 1:
      raise GNException("This script doesn't support multiple operators in "
                        'comparisons')

    if isinstance(compare.ops[0], ast.Eq):
      op = ' == '
    elif isinstance(compare.ops[0], ast.NotEq):
      op = ' != '
    else:
      raise GNException('Operator ' + str(compare.ops[0]) + ' not supported')

    if isinstance(compare.left, ast.Name):
      if isinstance(compare.comparators[0], ast.Name):  # var1 == var2
        left = self.visit_Name(compare.left)
        right = self.visit_Name(compare.comparators[0])
      elif isinstance(compare.comparators[0], ast.Num):  # var1 == 42
        left, right = TransformVariable(compare.left.id,
                                        compare.comparators[0].n)
      elif isinstance(compare.comparators[0], ast.Str):  # var1 == "some string"
        left, right = TransformVariable(compare.left.id,
                                        compare.comparators[0].s)
      else:
        raise GNException('Unknown RHS type ' + str(compare.comparators[0]))
    else:
      raise GNException('Non-variables on LHS of comparison are not supported')

    if right == 'true' and op == ' == ' or right == 'false' and op == ' != ':
      return left
    elif right == 'false' and op == ' == ' or right == 'true' and op == ' != ':
      return '!(' + left + ')'
    else:
      return left + op + right

  def generic_visit(self, node):
    raise GNException("I don't know how to convert node " + str(node))


class OSComparisonRewriter(ast.NodeTransformer):

  def visit_Compare(self, compare):  # pylint: disable=invalid-name
    """Substitute instances of comparisons involving the OS and os_posix
    variables with their known values in Compare nodes.

    Examples:
      ``OS == "starboard"`` -> ``True``
      ``OS != "starboard"`` -> ``False``
      ``OS == "linux"`` -> ``False``
      ``os_posix == 1`` -> ``False``
      ``os_bsd == 1`` -> ``False``
    """
    if len(compare.ops) != 1:
      raise GNException("This script doesn't support multiple operators in "
                        'comparisons')

    if not isinstance(compare.left, ast.Name):
      return compare

    elif compare.left.id == 'OS':
      if (isinstance(compare.comparators[0], ast.Str) and
          compare.comparators[0].s == 'starboard'):
        # OS == "starboard" -> True, OS != "starboard" -> False
        new_node = ast.Num(1 if isinstance(compare.ops[0], ast.Eq) else 0)
      else:
        # OS == "something else" -> False, OS != "something else" -> True
        new_node = ast.Num(0 if isinstance(compare.ops[0], ast.Eq) else 1)

      return ast.copy_location(new_node, compare)

    elif compare.left.id in {'os_posix', 'os_bsd'}:
      if (isinstance(compare.comparators[0], ast.Num) and
          compare.comparators[0].n == 0):
        # os_posix == 0 -> True, os_posix != 0 -> False
        # ditto for os_bsd
        new_node = ast.Num(1 if isinstance(compare.ops[0], ast.Eq) else 0)
      else:
        # os_posix == (not 0) -> False, os_posix != (not 0) -> True
        # ditto for os_bsd
        new_node = ast.Num(0 if isinstance(compare.ops[0], ast.Eq) else 1)

      return ast.copy_location(new_node, compare)

    else:
      return compare

  def visit_BoolOp(self, boolop):  # pylint: disable=invalid-name
    """Simplify BoolOp nodes by weeding out Falses and Trues resulting from
    the elimination of OS comparisons.
    """
    doing_and = isinstance(boolop.op, ast.And)
    new_values = map(self.visit, boolop.values)
    new_values_filtered = []

    for v in new_values:
      if isinstance(v, ast.Num):
        # "x and False", or "y or True" - short circuit
        if (doing_and and v.n == 0) or (not doing_and and v.n == 1):
          new_values_filtered = None
          break
        # "x and True", or "y or False" - skip the redundant value
        elif (doing_and and v.n == 1) or (not doing_and and v.n == 0):
          pass
        else:
          new_values_filtered.append(v)
      else:
        new_values_filtered.append(v)

    if new_values_filtered is None:
      new_node = ast.Num(0 if doing_and else 1)
    elif len(new_values_filtered) == 0:
      new_node = ast.Num(1 if doing_and else 0)
    elif len(new_values_filtered) == 1:
      new_node = new_values_filtered[0]
    else:
      new_node = ast.BoolOp(boolop.op, new_values_filtered)

    return ast.copy_location(new_node, boolop)


def Warn(msg):
  print >> sys.stderr, '\x1b[1;33mWarning:\x1b[0m', msg


def WarnAboutRemainingKeys(dic):
  for key in dic:
    Warn("I don't know what {} is".format(key))


def TransformVariable(var, value):
  """Given a variable and value, substitutes the variable name/value with
  the new name/new value from the variable_rewrites dict, if applicable.

  Example:
    ``('arm_neon', 1)`` -> ``('arm_use_neon', 'true')``
    ``('gl_type', 'none')`` -> ``('gl_type', 'none')``
  """
  if var in variable_rewrites:
    var, value_rewrites = variable_rewrites[var]
    if value_rewrites is not None:
      value = value_rewrites[value]

  return var, GYPValueToGNString(value)


def GYPValueToGNString(value, allow_dicts=True):
  """Returns a stringified GN equivalent of the Python value.

  allow_dicts indicates if this function will allow converting dictionaries
  to GN scopes. This is only possible at the top level, you can't nest a
  GN scope in a list, so this should be set to False for recursive calls."""

  if isinstance(value, str):
    if value.find('\n') >= 0:
      raise GNException("GN strings don't support newlines")
    # Escape characters
    ret = value.replace('\\', r'\\').replace('"', r'\"') \
               .replace('$', r'\$')
    # Convert variable substitutions
    ret = re.sub(r'[<>]\((\w+)\)', r'$\1', ret)
    return '"' + ret + '"'

  if isinstance(value, unicode):
    if value.find(u'\n') >= 0:
      raise GNException("GN strings don't support newlines")
    # Escape characters
    ret = value.replace(u'\\', ur'\\').replace(u'"', ur'\"') \
               .replace(u'$', ur'\$')
    # Convert variable substitutions
    ret = re.sub(ur'[<>]\((\w+)\)', ur'$\1', ret)
    return (u'"' + ret + u'"').encode('utf-8')

  if isinstance(value, bool):
    if value:
      return 'true'
    return 'false'

  if isinstance(value, list):
    return '[ %s ]' % ', '.join(GYPValueToGNString(v) for v in value)

  if isinstance(value, dict):
    if not allow_dicts:
      raise GNException('Attempting to recursively print a dictionary.')
    result = ''
    for key in sorted(value):
      if not isinstance(key, basestring):
        raise GNException('Dictionary key is not a string.')
      result += '%s = %s\n' % (key, GYPValueToGNString(value[key], False))
    return result

  if isinstance(value, int):
    return str(value)

  raise GNException('Unsupported type when printing to GN.')


def GYPTargetToGNString(target_dict):
  """Given a target dict, output the GN equivalent."""

  target_header_text = ''

  target_name = target_dict.pop('target_name')
  target_type = target_dict.pop('type')
  if target_type in {'executable', 'shared_library', 'static_library'}:
    if target_type == 'static_library':
      Warn('converting static library, check to see if it should be a '
           'source_set')
    target_header_text += '{}("{}") {{\n'.format(target_type, target_name)
  elif target_type == 'none':
    target_header_text += 'group("{}") {{\n'.format(target_name)
  elif target_type == '<(gtest_target_type)':
    target_header_text += 'test("{}") {{\n'.format(target_name)
  elif target_type == '<(final_executable_type)':
    target_header_text += 'final_executable("{}") {{\n'.format(target_name)
  elif target_type == '<(component)' or target_type == '<(library)':
    Warn('converting static library, check to see if it should be a '
         'source_set')
    target_header_text += 'static_library("{}") {{\n'.format(target_name)
  else:
    raise GNException("I don't understand target type {}".format(target_type))

  target_body_text, configs_text = \
      GYPTargetToGNString_Inner(target_dict, target_name)

  return configs_text + target_header_text + target_body_text + '}\n\n'


def ProcessIncludeExclude(dic, param):
  """Translate dic[param] and dic[param + '!'] lists to GN.

  Example input:
    {
      'sources': [ 'foo.cc', 'bar.cc', 'baz.cc' ],
      'sources!': [ 'bar.cc' ]
    }
  Example output:
    sources = [ 'foo.cc', 'bar.cc', 'baz.cc' ]
    sources -= [ 'bar.cc' ]
  """
  ret = ''
  if param in dic:
    value = dic.pop(param)
    ret += '{} = [ {} ]\n'.format(param, ', '.join(
        GYPValueToGNString(s) for s in value))
  if param + '!' in dic:
    value = dic.pop(param + '!')
    ret += '{} -= [ {} ]\n'.format(param, ', '.join(
        GYPValueToGNString(s) for s in value))
  ret += '\n'
  return ret


def ProcessDependentSettings(dependent_settings_dict, target_dict, param,
                             renamed_param, config_name):
  """Translates direct_dependent_settings and all_dependent_settings blocks
  to their GN equivalents. This is done by creating a new GN config, putting
  the settings in that config, and adding the config to the target's
  public_configs/all_dependent_configs. Returns a tuple of
  (target_text, config_text).

  Also eliminates the translated settings from the target_dict so they aren't
  translated twice.

  Example input:
    {
      'target_name': 'abc',
      'direct_dependent_settings': {
        'defines': [ "FOO" ]
      }
    }

  Example target text output:
    public_configs = [ ":abc_direct_config" ]

  Example config text output:
    config("abc_direct_config") {
      defines = [ "FOO" ]
    }
  """
  ret_target = ''
  ret_config = 'config("{}") {{\n'.format(config_name)

  def FilterList(key):
    if key in target_dict and key in dependent_settings_dict:
      filtered_list = sorted(
          set(target_dict[key]) - set(dependent_settings_dict[key]))
      if filtered_list:
        target_dict[key] = filtered_list
      else:
        del target_dict[key]

  for inner_param in [
      'include_dirs', 'defines', 'asmflags', 'cflags', 'cflags_c', 'cflags_cc',
      'cflags_objc', 'cflags_objcc', 'ldflags'
  ]:
    FilterList(inner_param)
    FilterList(inner_param + '!')
    ret_config += ProcessIncludeExclude(dependent_settings_dict, inner_param)

  if 'variables' in dependent_settings_dict:
    Warn("variables block inside {}. You'll need to handle that manually."
         .format(param))
    del dependent_settings_dict['variables']

  if 'conditions' in dependent_settings_dict:
    for i, cond_block in enumerate(dependent_settings_dict['conditions']):
      cond_config_name = '{}_{}'.format(config_name, i)
      t, c = GYPConditionToGNString(cond_block,
               lambda dsd: ProcessDependentSettings(dsd, target_dict, param,
                                                    renamed_param,
                                                    cond_config_name))
      ret_config += c
      ret_target += t
    del dependent_settings_dict['conditions']

  if 'target_conditions' in dependent_settings_dict:
    for i, cond_block in \
        enumerate(dependent_settings_dict['target_conditions']):
      cond_config_name = '{}_t{}'.format(config_name, i)
      t, c = GYPConditionToGNString(cond_block,
               lambda dsd: ProcessDependentSettings(dsd, target_dict, param,
                                                    renamed_param,
                                                    cond_config_name))
      ret_config += c
      ret_target += t
    del dependent_settings_dict['target_conditions']

  ret_config += '}\n\n'
  ret_target += '{} = [ ":{}" ]\n\n'.format(renamed_param, config_name)
  WarnAboutRemainingKeys(dependent_settings_dict)
  return ret_target, ret_config


def GYPTargetToGNString_Inner(target_dict, target_name):
  """Translates the body of a GYP target into a GN string."""
  configs_text = ''
  target_text = ''
  dependent_text = ''

  if 'variables' in target_dict:
    target_text += GYPVariablesToGNString(target_dict['variables'])
    del target_dict['variables']

  target_text += ProcessIncludeExclude(target_dict, 'sources')

  for param, renamed_param, config_name_elem in \
      [('direct_dependent_settings', 'public_configs', 'direct'),
       ('all_dependent_settings', 'all_dependent_configs', 'dependent')]:
    if param in target_dict:
      config_name = '{}_{}_config'.format(target_name, config_name_elem)
      # Append dependent_text to target_text after include_dirs/defines/etc.
      dependent_text, c = ProcessDependentSettings(
          target_dict[param], target_dict, param, renamed_param, config_name)
      configs_text += c
      del target_dict[param]

  for param in [
      'include_dirs', 'defines', 'asmflags', 'cflags', 'cflags_c', 'cflags_cc',
      'cflags_objc', 'cflags_objcc', 'ldflags'
  ]:
    target_text += ProcessIncludeExclude(target_dict, param)

  target_text += dependent_text

  if 'export_dependent_settings' in target_dict:
    target_text += GYPDependenciesToGNString(
        'public_deps', target_dict['export_dependent_settings'])

    # Remove dependencies covered here from the ordinary dependencies list
    target_dict['dependencies'] = sorted(
        set(target_dict['dependencies']) -
        set(target_dict['export_dependent_settings']))
    if not target_dict['dependencies']:
      del target_dict['dependencies']

    del target_dict['export_dependent_settings']

  if 'dependencies' in target_dict:
    target_text += GYPDependenciesToGNString('deps',
                                             target_dict['dependencies'])
    del target_dict['dependencies']

  if 'conditions' in target_dict:
    for cond_block in target_dict['conditions']:
      t, c = GYPConditionToGNString(
          cond_block, lambda td: GYPTargetToGNString_Inner(td, target_name))
      configs_text += c
      target_text += t
    del target_dict['conditions']

  if 'target_conditions' in target_dict:
    for cond_block in target_dict['target_conditions']:
      t, c = GYPConditionToGNString(
          cond_block, lambda td: GYPTargetToGNString_Inner(td, target_name))
      configs_text += c
      target_text += t
    del target_dict['target_conditions']

  WarnAboutRemainingKeys(target_dict)
  return target_text, configs_text


def GYPDependenciesToGNString(param, dep_list):
  r"""Translates a GYP dependency into a GN dependency. Tries to intelligently
  perform target renames as according to GN style conventions.

  Examples:
  (Note that <(DEPTH) has already been translated into // by the time this
  function is called)
  >>> GYPDependenciesToGNString('deps', ['//cobalt/math/math.gyp:math'])
  'deps = [ "//cobalt/math" ]\n\n'
  >>> GYPDependenciesToGNString('public_deps',
  ...                           ['//testing/gtest.gyp:gtest'])
  'public_deps = [ "//testing/gtest" ]\n\n'
  >>> GYPDependenciesToGNString('deps', ['//third_party/icu/icu.gyp:icui18n'])
  'deps = [ "//third_party/icu:icui18n" ]\n\n'
  >>> GYPDependenciesToGNString('deps',
  ...     ['//cobalt/browser/browser_bindings_gen.gyp:generated_types'])
  'deps = [ "//cobalt/browser/browser_bindings_gen:generated_types" ]\n\n'
  >>> GYPDependenciesToGNString('deps', ['allocator'])
  'deps = [ ":allocator" ]\n\n'
  >>> # Suppose the input file is in //cobalt/foo/bar/
  >>> GYPDependenciesToGNString('deps', ['../baz.gyp:quux'])
  'deps = [ "//cobalt/foo/baz:quux" ]\n\n'
  """
  new_dep_list = []
  for dep in dep_list:
    if dep in deps_substitutions:
      new_dep_list.append(deps_substitutions[dep])
    else:
      m1 = re.match(r'(.*/)?(\w+)/\2\.gyp:\2$', dep)
      m2 = re.match(r'(.*/)?(\w+)\.gyp:\2$', dep)
      m3 = re.match(r'(.*/)?(\w+)/\2.gyp:(\w+)$', dep)
      m4 = re.match(r'(.*)\.gyp:(\w+)$', dep)
      m5 = re.match(r'\w+', dep)
      if m1:
        new_dep = '{}{}'.format(m1.group(1) or '', m1.group(2))
      elif m2:
        new_dep = '{}{}'.format(m2.group(1) or '', m2.group(2))
      elif m3:
        new_dep = '{}{}:{}'.format(m3.group(1) or '', m3.group(2), m3.group(3))
      elif m4:
        new_dep = '{}:{}'.format(m4.group(1), m4.group(2))
      elif m5:
        new_dep = ':' + dep
      else:
        Warn("I don't know how to translate dependency " + dep)
        continue

      if not (new_dep.startswith('//') or new_dep.startswith(':') or
              os.path.isabs(new_dep)):
        # Rebase new_dep to be repository-absolute
        new_dep = os.path.normpath(repo_abs_input_file_dir + new_dep)

      new_dep_list.append(new_dep)

  quoted_deps = ['"{}"'.format(d) for d in new_dep_list]
  return '{} = [ {} ]\n\n'.format(param, ', '.join(quoted_deps))


def GYPVariablesToGNString(varblock):
  """Translates a GYP variables block into its GN equivalent, performing
  variable substitutions as necessary."""
  ret = ''

  if 'variables' in varblock:
    # Recursively flatten nested variables dicts.
    ret += GYPVariablesToGNString(varblock['variables'])

  for k, v in varblock.viewitems():
    if k in {'variables', 'conditions'}:
      continue

    if k.endswith('%'):
      k = k[:-1]

    if not k.endswith('!'):
      ret += '{} = {}\n'.format(*TransformVariable(k, v))
    else:
      ret += '{} -= {}\n'.format(*TransformVariable(k[:-1], v))

  if 'conditions' in varblock:
    for cond_block in varblock['conditions']:
      ret += GYPConditionToGNString(cond_block, GYPVariablesToGNString)[0]

  ret += '\n'
  return ret


def GYPConditionToGNString(cond_block, recursive_translate):
  """Translates a GYP condition block into a GN string. The recursive_translate
  param is a function that is called with the true subdict and the false
  subdict if applicable. The recursive_translate function returns either a
  single string that should go inside the if/else block, or a tuple of
  (target_text, config_text), in which the target_text goes inside the if/else
  block and the config_text goes outside.

  Returns a tuple (target_text, config_text), where config_text is the empty
  string if recursive_translate only returns one string.
  """
  cond = cond_block[0]
  iftrue = cond_block[1]
  iffalse = cond_block[2] if len(cond_block) == 3 else None

  ast_cond = ast.parse(cond, mode='eval')
  ast_cond = OSComparisonRewriter().visit(ast_cond)
  translated_cond = GYPCondToGNNodeVisitor().visit(ast_cond)

  if translated_cond == 'false' and iffalse is None:
    # if (false) { ... } -> nothing
    # Special cased to avoid printing warnings from the unnecessary translation
    # of the true clause
    return '', ''

  translated_iftrue = recursive_translate(iftrue)
  if isinstance(translated_iftrue, tuple):
    iftrue_text, aux_iftrue_text = translated_iftrue
  else:
    iftrue_text, aux_iftrue_text = translated_iftrue, ''

  if translated_cond == 'true':  # Tautology - just return the body
    return iftrue_text, aux_iftrue_text

  elif iffalse is None:  # Non-tautology, non-contradiction, no else clause
    return ('if (' + translated_cond + ') {\n' + iftrue_text + '}\n\n',
            aux_iftrue_text)

  else:  # Non-tautology, else clause present
    translated_iffalse = recursive_translate(iffalse)
    if isinstance(translated_iffalse, tuple):
      iffalse_text, aux_iffalse_text = translated_iffalse
    else:
      iffalse_text, aux_iffalse_text = translated_iffalse, ''

    if translated_cond == 'false':  # if (false) { blah } else { ... } -> ...
      return iffalse_text, aux_iffalse_text

    else:
      return ('if (' + translated_cond + ') {\n' + iftrue_text + '} else {\n' +
              iffalse_text + '}\n\n', aux_iftrue_text + aux_iffalse_text)


def ToplevelGYPToGNString(toplevel_dict):
  """Translates a toplevel GYP dict to GN. This is the main function which is
  called to perform the GYP to GN translation.
  """
  ret = ''

  if 'variables' in toplevel_dict:
    ret += GYPVariablesToGNString(toplevel_dict['variables'])
    del toplevel_dict['variables']

  if 'targets' in toplevel_dict:
    for t in toplevel_dict['targets']:
      ret += GYPTargetToGNString(t)
    del toplevel_dict['targets']

  if 'conditions' in toplevel_dict:
    for cond_block in toplevel_dict['conditions']:
      ret += GYPConditionToGNString(cond_block, ToplevelGYPToGNString)[0]
    del toplevel_dict['conditions']

  if 'target_conditions' in toplevel_dict:
    for cond_block in toplevel_dict['target_conditions']:
      ret += GYPConditionToGNString(cond_block, ToplevelGYPToGNString)[0]
    del toplevel_dict['target_conditions']

  WarnAboutRemainingKeys(toplevel_dict)
  return ret


def LoadPythonDictionary(path):
  with open(path, 'r') as fin:
    file_string = fin.read()
  try:
    file_data = eval(file_string, {'__builtins__': None}, None)  # pylint: disable=eval-used
  except SyntaxError, e:
    e.filename = path
    raise
  except Exception, 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

  return file_data


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

  Replaces all substrings of the "search_for" with "replace_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.viewitems():
      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 CalculatePaths(filename):
  global repo_abs_input_file_dir

  abs_input_file_dir = os.path.abspath(os.path.dirname(filename))
  abs_repo_root = cobalt.tools.paths.REPOSITORY_ROOT + '/'
  if not abs_input_file_dir.startswith(abs_repo_root):
    raise ValueError('Input file is not in repository')

  repo_abs_input_file_dir = '//' + abs_input_file_dir[len(abs_repo_root):] + '/'


def LoadDepsSubstitutions():
  dirname = os.path.dirname(__file__)
  if dirname:
    dirname += '/'

  with open(dirname + 'deps_substitutions.txt', 'r') as f:
    for line in itertools.ifilter(lambda lin: lin.strip(), f):
      dep, new_dep = line.split()
      deps_substitutions[dep.replace('<(DEPTH)/', '//')] = new_dep


def LoadVariableRewrites():
  dirname = os.path.dirname(__file__)
  if dirname:
    dirname += '/'

  vr = LoadPythonDictionary(dirname + 'variable_rewrites.dict')

  if 'rewrites' in vr:
    for old_name, rewrite in vr['rewrites'].viewitems():
      variable_rewrites[old_name] = VariableRewrite(*rewrite)

  if 'renames' in vr:
    for old_name, new_name in vr['renames'].viewitems():
      variable_rewrites[old_name] = VariableRewrite(new_name, None)

  if 'booleans' in vr:
    bool_mapping = {0: False, 1: True}
    for v in vr['booleans']:
      if v in variable_rewrites:
        variable_rewrites[v] = \
            variable_rewrites[v]._replace(value_rewrites=bool_mapping)
      else:
        variable_rewrites[v] = VariableRewrite(v, bool_mapping)


def main():
  parser = argparse.ArgumentParser(description='Convert a subset of GYP to GN.')
  parser.add_argument(
      '-r',
      '--replace',
      action='append',
      help='Replaces substrings. If passed a=b, replaces all '
      'substrs a with b.')
  parser.add_argument('file', help='The GYP file to read.')
  args = parser.parse_args()

  CalculatePaths(args.file)

  data = LoadPythonDictionary(args.file)
  if args.replace:
    # Do replacements for all specified patterns.
    for replace in args.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])
  # Also replace <(DEPTH)/ with //
  data = ReplaceSubstrings(data, '<(DEPTH)/', '//')

  LoadDepsSubstitutions()
  LoadVariableRewrites()

  print ToplevelGYPToGNString(data)


if __name__ == '__main__':
  main()
