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

import argparse
import convert_gn_xcodeproj
import errno
import os
import re
import shutil
import subprocess
import sys
import tempfile
import ConfigParser

try:
  import cStringIO as StringIO
except ImportError:
  import StringIO


SUPPORTED_TARGETS = ('iphoneos', 'iphonesimulator')
SUPPORTED_CONFIGS = ('Debug', 'Release', 'Profile', 'Official', 'Coverage')


class ConfigParserWithStringInterpolation(ConfigParser.SafeConfigParser):

  '''A .ini file parser that supports strings and environment variables.'''

  ENV_VAR_PATTERN = re.compile(r'\$([A-Za-z0-9_]+)')

  def values(self, section):
    return map(
        lambda (k, v): self._UnquoteString(self._ExpandEnvVar(v)),
        ConfigParser.SafeConfigParser.items(self, section))

  def getstring(self, section, option):
    return self._UnquoteString(self._ExpandEnvVar(self.get(section, option)))

  def _UnquoteString(self, string):
    if not string or string[0] != '"' or string[-1] != '"':
      return string
    return string[1:-1]

  def _ExpandEnvVar(self, value):
    match = self.ENV_VAR_PATTERN.search(value)
    if not match:
      return value
    name, (begin, end) = match.group(1), match.span(0)
    prefix, suffix = value[:begin], self._ExpandEnvVar(value[end:])
    return prefix + os.environ.get(name, '') + suffix

class GnGenerator(object):

  '''Holds configuration for a build and method to generate gn default files.'''

  FAT_BUILD_DEFAULT_ARCH = '64-bit'

  TARGET_CPU_VALUES = {
    'iphoneos': {
      '32-bit': '"arm"',
      '64-bit': '"arm64"',
    },
    'iphonesimulator': {
      '32-bit': '"x86"',
      '64-bit': '"x64"',
    }
  }

  def __init__(self, settings, config, target):
    assert target in SUPPORTED_TARGETS
    assert config in SUPPORTED_CONFIGS
    self._settings = settings
    self._config = config
    self._target = target

  def _GetGnArgs(self):
    """Build the list of arguments to pass to gn.

    Returns:
      A list of tuple containing gn variable names and variable values (it
      is not a dictionary as the order needs to be preserved).
    """
    args = []

    # build/config/ios/ios_sdk.gni asserts that goma is not enabled when
    # building Official, so ignore the value of goma.enabled when creating
    # args.gn for Official.
    if self._config != 'Official':
      if self._settings.getboolean('goma', 'enabled'):
        args.append(('use_goma', True))
        goma_dir = self._settings.getstring('goma', 'install')
        if goma_dir:
          args.append(('goma_dir', '"%s"' % os.path.expanduser(goma_dir)))

    args.append(('is_debug', self._config in ('Debug', 'Coverage')))
    args.append(('enable_dsyms', self._config in ('Profile', 'Official')))
    args.append(('enable_stripping', 'enable_dsyms'))
    args.append(('is_official_build', self._config == 'Official'))
    args.append(('is_chrome_branded', 'is_official_build'))
    args.append(('use_xcode_clang', 'false'))
    args.append(('use_clang_coverage', self._config == 'Coverage'))
    args.append(('is_component_build', False))

    if os.environ.get('FORCE_MAC_TOOLCHAIN', '0') == '1':
      args.append(('use_system_xcode', False))

    cpu_values = self.TARGET_CPU_VALUES[self._target]
    build_arch = self._settings.getstring('build', 'arch')
    if build_arch == 'fat':
      target_cpu = cpu_values[self.FAT_BUILD_DEFAULT_ARCH]
      args.append(('target_cpu', target_cpu))
      args.append(('additional_target_cpus',
          [cpu for cpu in cpu_values.itervalues() if cpu != target_cpu]))
    else:
      args.append(('target_cpu', cpu_values[build_arch]))

    # Add user overrides after the other configurations so that they can
    # refer to them and override them.
    args.extend(self._settings.items('gn_args'))
    return args


  def Generate(self, gn_path, root_path, out_path):
    buf = StringIO.StringIO()
    self.WriteArgsGn(buf)
    WriteToFileIfChanged(
        os.path.join(out_path, 'args.gn'),
        buf.getvalue(),
        overwrite=True)

    subprocess.check_call(
        self.GetGnCommand(gn_path, root_path, out_path, True))

  def CreateGnRules(self, gn_path, root_path, out_path):
    buf = StringIO.StringIO()
    self.WriteArgsGn(buf)
    WriteToFileIfChanged(
        os.path.join(out_path, 'args.gn'),
        buf.getvalue(),
        overwrite=True)

    buf = StringIO.StringIO()
    gn_command = self.GetGnCommand(gn_path, root_path, out_path, False)
    self.WriteBuildNinja(buf, gn_command)
    WriteToFileIfChanged(
        os.path.join(out_path, 'build.ninja'),
        buf.getvalue(),
        overwrite=False)

    buf = StringIO.StringIO()
    self.WriteBuildNinjaDeps(buf)
    WriteToFileIfChanged(
        os.path.join(out_path, 'build.ninja.d'),
        buf.getvalue(),
        overwrite=False)

  def WriteArgsGn(self, stream):
    stream.write('# This file was generated by setup-gn.py. Do not edit\n')
    stream.write('# but instead use ~/.setup-gn or $repo/.setup-gn files\n')
    stream.write('# to configure settings.\n')
    stream.write('\n')

    if self._settings.has_section('$imports$'):
      for import_rule in self._settings.values('$imports$'):
        stream.write('import("%s")\n' % import_rule)
      stream.write('\n')

    gn_args = self._GetGnArgs()
    for name, value in gn_args:
      if isinstance(value, bool):
        stream.write('%s = %s\n' % (name, str(value).lower()))
      elif isinstance(value, list):
        stream.write('%s = [%s' % (name, '\n' if len(value) > 1 else ''))
        if len(value) == 1:
          prefix = ' '
          suffix = ' '
        else:
          prefix = '  '
          suffix = ',\n'
        for item in value:
          if isinstance(item, bool):
            stream.write('%s%s%s' % (prefix, str(item).lower(), suffix))
          else:
            stream.write('%s%s%s' % (prefix, item, suffix))
        stream.write(']\n')
      else:
        stream.write('%s = %s\n' % (name, value))

  def WriteBuildNinja(self, stream, gn_command):
    stream.write('rule gn\n')
    stream.write('  command = %s\n' % NinjaEscapeCommand(gn_command))
    stream.write('  description = Regenerating ninja files\n')
    stream.write('\n')
    stream.write('build build.ninja: gn\n')
    stream.write('  generator = 1\n')
    stream.write('  depfile = build.ninja.d\n')

  def WriteBuildNinjaDeps(self, stream):
    stream.write('build.ninja: nonexistant_file.gn\n')

  def GetGnCommand(self, gn_path, src_path, out_path, generate_xcode_project):
    gn_command = [ gn_path, '--root=%s' % os.path.realpath(src_path), '-q' ]
    if generate_xcode_project:
      gn_command.append('--ide=xcode')
      gn_command.append('--root-target=gn_all')
      gn_command.append('--ninja-executable=autoninja')
      if self._settings.has_section('filters'):
        target_filters = self._settings.values('filters')
        if target_filters:
          gn_command.append('--filters=%s' % ';'.join(target_filters))
    else:
      gn_command.append('--check')
    gn_command.append('gen')
    gn_command.append('//%s' %
        os.path.relpath(os.path.abspath(out_path), os.path.abspath(src_path)))
    return gn_command


def WriteToFileIfChanged(filename, content, overwrite):
  '''Write |content| to |filename| if different. If |overwrite| is False
  and the file already exists it is left untouched.'''
  if os.path.exists(filename):
    if not overwrite:
      return
    with open(filename) as file:
      if file.read() == content:
        return
  if not os.path.isdir(os.path.dirname(filename)):
    os.makedirs(os.path.dirname(filename))
  with open(filename, 'w') as file:
    file.write(content)


def NinjaNeedEscape(arg):
  '''Returns True if |arg| needs to be escaped when written to .ninja file.'''
  return ':' in arg or '*' in arg or ';' in arg


def NinjaEscapeCommand(command):
  '''Escapes |command| in order to write it to .ninja file.'''
  result = []
  for arg in command:
    if NinjaNeedEscape(arg):
      arg = arg.replace(':', '$:')
      arg = arg.replace(';', '\\;')
      arg = arg.replace('*', '\\*')
    else:
      result.append(arg)
  return ' '.join(result)


def FindGn():
  '''Returns absolute path to gn binary looking at the PATH env variable.'''
  for path in os.environ['PATH'].split(os.path.pathsep):
    gn_path = os.path.join(path, 'gn')
    if os.path.isfile(gn_path) and os.access(gn_path, os.X_OK):
      return gn_path
  return None


def GenerateXcodeProject(gn_path, root_dir, out_dir, settings):
  '''Convert GN generated Xcode project into multi-configuration Xcode
  project.'''

  temp_path = tempfile.mkdtemp(prefix=os.path.abspath(
      os.path.join(out_dir, '_temp')))
  try:
    generator = GnGenerator(settings, 'Debug', 'iphonesimulator')
    generator.Generate(gn_path, root_dir, temp_path)
    convert_gn_xcodeproj.ConvertGnXcodeProject(
        root_dir,
        os.path.join(temp_path),
        os.path.join(out_dir, 'build'),
        SUPPORTED_CONFIGS)
  finally:
    if os.path.exists(temp_path):
      shutil.rmtree(temp_path)


def GenerateGnBuildRules(gn_path, root_dir, out_dir, settings):
  '''Generates all template configurations for gn.'''
  for config in SUPPORTED_CONFIGS:
    for target in SUPPORTED_TARGETS:
      build_dir = os.path.join(out_dir, '%s-%s' % (config, target))
      generator = GnGenerator(settings, config, target)
      generator.CreateGnRules(gn_path, root_dir, build_dir)


def Main(args):
  default_root = os.path.normpath(os.path.join(
      os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))

  parser = argparse.ArgumentParser(
      description='Generate build directories for use with gn.')
  parser.add_argument(
      'root', default=default_root, nargs='?',
      help='root directory where to generate multiple out configurations')
  parser.add_argument(
      '--import', action='append', dest='import_rules', default=[],
      help='path to file defining default gn variables')
  args = parser.parse_args(args)

  # Load configuration (first global and then any user overrides).
  settings = ConfigParserWithStringInterpolation()
  settings.read([
      os.path.splitext(__file__)[0] + '.config',
      os.path.expanduser('~/.setup-gn'),
  ])

  # Add private sections corresponding to --import argument.
  if args.import_rules:
    settings.add_section('$imports$')
    for i, import_rule in enumerate(args.import_rules):
      if not import_rule.startswith('//'):
        import_rule = '//%s' % os.path.relpath(
            os.path.abspath(import_rule), os.path.abspath(args.root))
      settings.set('$imports$', '$rule%d$' % i, import_rule)

  # Validate settings.
  if settings.getstring('build', 'arch') not in ('64-bit', '32-bit', 'fat'):
    sys.stderr.write('ERROR: invalid value for build.arch: %s\n' %
        settings.getstring('build', 'arch'))
    sys.exit(1)

  # Find gn binary in PATH.
  gn_path = FindGn()
  if gn_path is None:
    sys.stderr.write('ERROR: cannot find gn in PATH\n')
    sys.exit(1)

  out_dir = os.path.join(args.root, 'out')
  if not os.path.isdir(out_dir):
    os.makedirs(out_dir)

  GenerateXcodeProject(gn_path, args.root, out_dir, settings)
  GenerateGnBuildRules(gn_path, args.root, out_dir, settings)


if __name__ == '__main__':
  sys.exit(Main(sys.argv[1:]))
