#!/usr/bin/python

# Copyright 2011 The Android Open Source Project
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This script is a wrapper which invokes gyp with the correct --depth argument,
# and supports the automatic regeneration of build files if all.gyp is
# changed (Linux-only).

import glob
import os
import platform
import shlex
import sys

script_dir = os.path.abspath(os.path.dirname(__file__))

# Directory within which we can find the gyp source.
gyp_source_dir = os.path.join(script_dir, 'third_party', 'externals', 'gyp')

# Directory within which we can find most of Skia's gyp configuration files.
gyp_config_dir = os.path.join(script_dir, 'gyp')

# Ensure we import our current gyp source's module, not any version
# pre-installed in your PYTHONPATH.
sys.path.insert(0, os.path.join(gyp_source_dir, 'pylib'))
import gyp

ENVVAR_GYP_GENERATORS = 'GYP_GENERATORS'


def additional_include_files(args=[]):
  # 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.
  # We do this, rather than including common.gypi explicitly in all our gyp
  # files, so that gyp files we use but do not maintain (e.g.,
  # third_party/externals/libjpeg/libjpeg.gyp) will include common.gypi too.
  AddInclude(os.path.join(gyp_config_dir, 'common.gypi'))

  return result

# Return the directory where all the build files are to be written.
def get_output_dir():
  # SKIA_OUT can be any directory either as a child of the standard out/
  # directory or any given location on the file system (e.g. /tmp/skia)
  output_dir = os.getenv('SKIA_OUT')

  if not output_dir:
    return os.path.join(os.path.abspath(script_dir), 'out')

  if (sys.platform.startswith('darwin') and
      (not os.getenv(ENVVAR_GYP_GENERATORS) or
       'xcode' in os.getenv(ENVVAR_GYP_GENERATORS))):
    print 'ERROR: variable SKIA_OUT is not valid on Mac (using xcodebuild)'
    sys.exit(-1);

  if os.path.isabs(output_dir):
    return output_dir
  else:
    return os.path.join(os.path.abspath(script_dir), output_dir)


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

  if not os.getenv(ENVVAR_GYP_GENERATORS):
    print ('%s environment variable not set, using default' %
           ENVVAR_GYP_GENERATORS)
    if sys.platform.startswith('darwin'):
      default_gyp_generators = 'ninja,xcode'
    elif sys.platform.startswith('win'):
      default_gyp_generators = 'ninja,msvs'
    elif sys.platform.startswith('cygwin'):
      default_gyp_generators = 'ninja,msvs'
    else:
      default_gyp_generators = 'ninja'
    os.environ[ENVVAR_GYP_GENERATORS] = default_gyp_generators
  print '%s is "%s"' % (ENVVAR_GYP_GENERATORS, os.getenv(ENVVAR_GYP_GENERATORS))

  # Set CWD to the directory containing this script.
  # This allows us to launch it from other directories, in spite of gyp's
  # finickyness about the current working directory.
  # See http://b.corp.google.com/issue?id=5019517 ('Linux make build
  # (from out dir) no longer runs skia_gyp correctly')
  os.chdir(os.path.abspath(script_dir))

  # 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, then fall back to assuming 'skia.gyp' from the
  # same directory as the script.
  # The gypfile must be passed as a relative path, not an absolute path,
  # or else the gyp code doesn't write into the proper output dir.
  if not gyp_file_specified:
    args.append('skia.gyp')

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

  # Tell gyp to write the build files into output_dir.
  args.extend(['--generator-output', os.path.abspath(get_output_dir())])

  # Tell ninja to write its output into the same directory.
  args.extend(['-Goutput_dir=.'])

  # By default, we build 'most' instead of 'all' or 'everything'. See skia.gyp.
  args.extend(['-Gdefault_target=most'])

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

  if '--dry-run' in args:
    args.remove('--dry-run')
    print gyp_source_dir, ' '.join(args)
  else:
    # Off we go...
    sys.exit(gyp.main(args))
