#!/usr/bin/python
#
# Copyright 2010 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This script is wrapper for V8 that adds some support for how GYP
# is invoked by V8 beyond what can be done in the gclient hooks.

import glob
import os
import shlex
import sys

script_dir = os.path.dirname(__file__)
v8_root = os.path.normpath(os.path.join(script_dir, os.pardir))

sys.path.insert(0, os.path.join(v8_root, 'build', 'gyp', 'pylib'))
import gyp

def apply_gyp_environment(file_path=None):
  """
  Reads in a *.gyp_env file and applies the valid keys to os.environ.
  """
  if not file_path or not os.path.exists(file_path):
    return
  file_contents = open(file_path).read()
  try:
    file_data = eval(file_contents, {'__builtins__': None}, None)
  except SyntaxError, e:
    e.filename = os.path.abspath(file_path)
    raise
  supported_vars = ( 'V8_GYP_FILE',
                     'V8_GYP_SYNTAX_CHECK',
                     'GYP_DEFINES',
                     'GYP_GENERATOR_FLAGS',
                     'GYP_GENERATOR_OUTPUT', )
  for var in supported_vars:
    val = file_data.get(var)
    if val:
      if var in os.environ:
        print 'INFO: Environment value for "%s" overrides value in %s.' % (
            var, os.path.abspath(file_path)
        )
      else:
        os.environ[var] = val

def additional_include_files(args=[]):
  """
  Returns a list of additional (.gypi) files to include, without
  duplicating ones that are already specified on the command line.
  """
  # Determine the include files specified on the command line.
  # This doesn't cover all the different option formats you can use,
  # but it's mainly intended to avoid duplicating flags on the automatic
  # makefile regeneration which only uses this format.
  specified_includes = set()
  for arg in args:
    if arg.startswith('-I') and len(arg) > 2:
      specified_includes.add(os.path.realpath(arg[2:]))

  result = []
  def AddInclude(path):
    if os.path.realpath(path) not in specified_includes:
      result.append(path)

  # Always include common.gypi & features_override.gypi
  AddInclude(os.path.join(script_dir, 'common.gypi'))

  # Optionally add supplemental .gypi files if present.
  supplements = glob.glob(os.path.join(v8_root, '*', 'supplement.gypi'))
  for supplement in supplements:
    AddInclude(supplement)

  return result

if __name__ == '__main__':
  args = sys.argv[1:]

  if 'SKIP_V8_GYP_ENV' not in os.environ:
    # Update the environment based on v8.gyp_env
    gyp_env_path = os.path.join(os.path.dirname(v8_root), 'v8.gyp_env')
    apply_gyp_environment(gyp_env_path)

  # This could give false positives since it doesn't actually do real option
  # parsing.  Oh well.
  gyp_file_specified = False
  for arg in args:
    if arg.endswith('.gyp'):
      gyp_file_specified = True
      break

  # If we didn't get a file, check an env var, and then fall back to
  # assuming 'all.gyp' from the same directory as the script.
  if not gyp_file_specified:
    gyp_file = os.environ.get('V8_GYP_FILE')
    if gyp_file:
      # Note that V8_GYP_FILE values can't have backslashes as
      # path separators even on Windows due to the use of shlex.split().
      args.extend(shlex.split(gyp_file))
    else:
      args.append(os.path.join(script_dir, 'all.gyp'))

  args.extend(['-I' + i for i in additional_include_files(args)])

  # There shouldn't be a circular dependency relationship between .gyp files
  args.append('--no-circular-check')

  # Set the GYP DEPTH variable to the root of the V8 project.
  args.append('--depth=' + v8_root)

  # If V8_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
  # to enfore syntax checking.
  syntax_check = os.environ.get('V8_GYP_SYNTAX_CHECK')
  if syntax_check and int(syntax_check):
    args.append('--check')

  print 'Updating projects from gyp files...'
  sys.stdout.flush()

  # Off we go...
  sys.exit(gyp.main(args))
