# Copyright (c) 2014 Google Inc. 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 is intended for use as a GYP_GENERATOR. It takes as input (by way of
the generator flag file_path) the list of relative file paths to consider. If
any target has at least one of the paths as a source (or input to an action or
rule) then 'Found dependency' is output, otherwise 'No dependencies' is output.
"""

import gyp.common
import gyp.ninja_syntax as ninja_syntax
import os
import posixpath

generator_supports_multiple_toolsets = True

generator_wants_static_library_dependencies_adjusted = False

generator_default_variables = {
}
for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
                'LIB_DIR', 'SHARED_LIB_DIR']:
  generator_default_variables[dirname] = '!!!'

for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
               'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
               'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
               'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
               'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
               'CONFIGURATION_NAME']:
  generator_default_variables[unused] = ''

def __MakeRelativeTargetName(path):
  """Converts a gyp target name into a relative name. For example, the path to a
  gyp file may be something like c:\foo\bar.gyp:target, this converts it to
  bar.gyp.
  """
  prune_path = os.getcwd()
  if path.startswith(prune_path):
    path = path[len(prune_path):]
    if len(path) and path.startswith(os.sep):
      path = path[len(os.sep):]
  # Gyp paths are always posix style.
  path = path.replace('\\', '/')
  if path.endswith('#target'):
    path = path[0:len(path) - len('#target')]
  return path

def __ExtractBasePath(target):
  """Extracts the path components of the specified gyp target path."""
  last_index = target.rfind('/')
  if last_index == -1:
    return ''
  return target[0:(last_index + 1)]

def __ResolveParent(path, base_path_components):
  """Resolves |path|, which starts with at least one '../'. Returns an empty
  string if the path shouldn't be considered. See __AddSources() for a
  description of |base_path_components|."""
  depth = 0
  while path.startswith('../'):
    depth += 1
    path = path[3:]
  # Relative includes may go outside the source tree. For example, an action may
  # have inputs in /usr/include, which are not in the source tree.
  if depth > len(base_path_components):
    return ''
  if depth == len(base_path_components):
    return path
  return '/'.join(base_path_components[0:len(base_path_components) - depth]) + \
      '/' + path

def __AddSources(sources, base_path, base_path_components, result):
  """Extracts valid sources from |sources| and adds them to |result|. Each
  source file is relative to |base_path|, but may contain '..'. To make
  resolving '..' easier |base_path_components| contains each of the
  directories in |base_path|. Additionally each source may contain variables.
  Such sources are ignored as it is assumed dependencies on them are expressed
  and tracked in some other means."""
  # NOTE: gyp paths are always posix style.
  for source in sources:
    if not len(source) or source.startswith('!!!') or source.startswith('$'):
      continue
    # variable expansion may lead to //.
    source = source[0] + source[1:].replace('//', '/')
    if source.startswith('../'):
      source = __ResolveParent(source, base_path_components)
      if len(source):
        result.append(source)
      continue
    result.append(base_path + source)

def __ExtractSourcesFromAction(action, base_path, base_path_components,
                               results):
  if 'inputs' in action:
    __AddSources(action['inputs'], base_path, base_path_components, results)

def __ExtractSources(target, target_dict):
  base_path = posixpath.dirname(target)
  base_path_components = base_path.split('/')
  # Add a trailing '/' so that __AddSources() can easily build paths.
  if len(base_path):
    base_path += '/'
  results = []
  if 'sources' in target_dict:
    __AddSources(target_dict['sources'], base_path, base_path_components,
                 results)
  # Include the inputs from any actions. Any changes to these effect the
  # resulting output.
  if 'actions' in target_dict:
    for action in target_dict['actions']:
      __ExtractSourcesFromAction(action, base_path, base_path_components,
                                 results)
  if 'rules' in target_dict:
    for rule in target_dict['rules']:
      __ExtractSourcesFromAction(rule, base_path, base_path_components, results)

  return results

class Target(object):
  """Holds information about a particular target:
  sources: set of source files defined by this target. This includes inputs to
           actions and rules.
  deps: list of direct dependencies."""
  def __init__(self):
    self.sources = []
    self.deps = []

def __GenerateTargets(target_list, target_dicts):
  """Generates a dictionary with the key the name of a target and the value a
  Target."""
  targets = {}

  # Queue of targets to visit.
  targets_to_visit = target_list[:]

  while len(targets_to_visit) > 0:
    absolute_target_name = targets_to_visit.pop()
    # |absolute_target| may be an absolute path and may include #target.
    # References to targets are relative, so we need to clean the name.
    relative_target_name = __MakeRelativeTargetName(absolute_target_name)
    if relative_target_name in targets:
      continue

    target = Target()
    targets[relative_target_name] = target
    target.sources.extend(__ExtractSources(relative_target_name,
                                           target_dicts[absolute_target_name]))

    for dep in target_dicts[absolute_target_name].get('dependencies', []):
      targets[relative_target_name].deps.append(__MakeRelativeTargetName(dep))
      targets_to_visit.append(dep)

  return targets

def __GetFiles(params):
  """Returns the list of files to analyze, or None if none specified."""
  generator_flags = params.get('generator_flags', {})
  file_path = generator_flags.get('file_path', None)
  if not file_path:
    return None
  try:
    f = open(file_path, 'r')
    result = []
    for file_name in f:
      if file_name.endswith('\n'):
        file_name = file_name[0:len(file_name) - 1]
      if len(file_name):
        result.append(file_name)
    f.close()
    return result
  except IOError:
    print 'Unable to open file', file_path
  return None

def CalculateVariables(default_variables, params):
  """Calculate additional variables for use in the build (called by gyp)."""
  flavor = gyp.common.GetFlavor(params)
  if flavor == 'mac':
    default_variables.setdefault('OS', 'mac')
  elif flavor == 'win':
    default_variables.setdefault('OS', 'win')
    # Copy additional generator configuration data from VS, which is shared
    # by the Windows Ninja generator.
    import gyp.generator.msvs as msvs_generator
    generator_additional_non_configuration_keys = getattr(msvs_generator,
        'generator_additional_non_configuration_keys', [])
    generator_additional_path_sections = getattr(msvs_generator,
        'generator_additional_path_sections', [])

    gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
  else:
    operating_system = flavor
    if flavor == 'android':
      operating_system = 'linux'  # Keep this legacy behavior for now.
    default_variables.setdefault('OS', operating_system)

def GenerateOutput(target_list, target_dicts, data, params):
  """Called by gyp as the final stage. Outputs results."""
  files = __GetFiles(params)
  if not files:
    print 'Must specify files to analyze via file_path generator flag'
    return

  targets = __GenerateTargets(target_list, target_dicts)

  files_set = frozenset(files)
  found_in_all_sources = 0
  for target_name, target in targets.iteritems():
    sources = files_set.intersection(target.sources)
    if len(sources):
      print 'Found dependency'
      return

  print 'No dependencies'
