#!/usr/bin/env python
# Copyright 2016 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Script to generate V8's gn arguments based on common developer defaults
or builder configurations.

Goma is used by default if detected. The compiler proxy is assumed to run.

This script can be added to the PATH and be used on other checkouts. It always
runs for the checkout nesting the CWD.

Configurations of this script live in infra/mb/mb_config.pyl.

Available actions are: {gen,list}. Omitting the action defaults to "gen".

-------------------------------------------------------------------------------

Examples:

# Generate the ia32.release config in out.gn/ia32.release.
v8gen.py ia32.release

# Generate into out.gn/foo without goma auto-detect.
v8gen.py gen -b ia32.release foo --no-goma

# Pass additional gn arguments after -- (don't use spaces within gn args).
v8gen.py ia32.optdebug -- v8_enable_slow_dchecks=true

# Generate gn arguments of 'V8 Linux64 - builder' from 'client.v8'. To switch
# off goma usage here, the args.gn file must be edited manually.
v8gen.py -m client.v8 -b 'V8 Linux64 - builder'

# Show available configurations.
v8gen.py list

-------------------------------------------------------------------------------
"""

import argparse
import os
import re
import subprocess
import sys

CONFIG = os.path.join('infra', 'mb', 'mb_config.pyl')
GOMA_DEFAULT = os.path.join(os.path.expanduser("~"), 'goma')
OUT_DIR = 'out.gn'

TOOLS_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(os.path.join(TOOLS_PATH, 'mb'))

import mb


def _sanitize_nonalpha(text):
  return re.sub(r'[^a-zA-Z0-9.]', '_', text)


class GenerateGnArgs(object):
  def __init__(self, args):
    # Split args into this script's arguments and gn args passed to the
    # wrapped gn.
    index = args.index('--') if '--' in args else len(args)
    self._options = self._parse_arguments(args[:index])
    self._gn_args = args[index + 1:]

  def _parse_arguments(self, args):
    self.parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.RawTextHelpFormatter,
    )

    def add_common_options(p):
      p.add_argument(
          '-m', '--master', default='developer_default',
          help='config group or master from mb_config.pyl - default: '
               'developer_default')
      p.add_argument(
          '-v', '--verbosity', action='count',
          help='print wrapped commands (use -vv to print output of wrapped '
               'commands)')

    subps = self.parser.add_subparsers()

    # Command: gen.
    gen_cmd = subps.add_parser(
        'gen', help='generate a new set of build files (default)')
    gen_cmd.set_defaults(func=self.cmd_gen)
    add_common_options(gen_cmd)
    gen_cmd.add_argument(
        'outdir', nargs='?',
        help='optional gn output directory')
    gen_cmd.add_argument(
        '-b', '--builder',
        help='build configuration or builder name from mb_config.pyl, e.g. '
             'x64.release')
    gen_cmd.add_argument(
        '-p', '--pedantic', action='store_true',
        help='run gn over command-line gn args to catch errors early')

    goma = gen_cmd.add_mutually_exclusive_group()
    goma.add_argument(
        '-g' , '--goma',
        action='store_true', default=None, dest='goma',
        help='force using goma')
    goma.add_argument(
        '--nogoma', '--no-goma',
        action='store_false', default=None, dest='goma',
        help='don\'t use goma auto detection - goma might still be used if '
             'specified as a gn arg')

    # Command: list.
    list_cmd = subps.add_parser(
        'list', help='list available configurations')
    list_cmd.set_defaults(func=self.cmd_list)
    add_common_options(list_cmd)

    # Default to "gen" unless global help is requested.
    if not args or args[0] not in subps.choices.keys() + ['-h', '--help']:
      args = ['gen'] + args

    return self.parser.parse_args(args)

  def cmd_gen(self):
    if not self._options.outdir and not self._options.builder:
      self.parser.error('please specify either an output directory or '
                        'a builder/config name (-b), e.g. x64.release')

    if not self._options.outdir:
      # Derive output directory from builder name.
      self._options.outdir = _sanitize_nonalpha(self._options.builder)
    else:
      # Also, if this should work on windows, we might need to use \ where
      # outdir is used as path, while using / if it's used in a gn context.
      if self._options.outdir.startswith('/'):
        self.parser.error(
            'only output directories relative to %s are supported' % OUT_DIR)

    if not self._options.builder:
      # Derive builder from output directory.
      self._options.builder = self._options.outdir

    # Check for builder/config in mb config.
    if self._options.builder not in self._mbw.masters[self._options.master]:
      print '%s does not exist in %s for %s' % (
          self._options.builder, CONFIG, self._options.master)
      return 1

    # TODO(machenbach): Check if the requested configurations has switched to
    # gn at all.

    # The directories are separated with slashes in a gn context (platform
    # independent).
    gn_outdir = '/'.join([OUT_DIR, self._options.outdir])

    # Call MB to generate the basic configuration.
    self._call_cmd([
      sys.executable,
      '-u', os.path.join('tools', 'mb', 'mb.py'),
      'gen',
      '-f', CONFIG,
      '-m', self._options.master,
      '-b', self._options.builder,
      gn_outdir,
    ])

    # Handle extra gn arguments.
    gn_args_path = os.path.join(OUT_DIR, self._options.outdir, 'args.gn')

    # Append command-line args.
    modified = self._append_gn_args(
        'command-line', gn_args_path, '\n'.join(self._gn_args))

    # Append goma args.
    # TODO(machenbach): We currently can't remove existing goma args from the
    # original config. E.g. to build like a bot that uses goma, but switch
    # goma off.
    modified |= self._append_gn_args(
        'goma', gn_args_path, self._goma_args)

    # Regenerate ninja files to check for errors in the additional gn args.
    if modified and self._options.pedantic:
      self._call_cmd(['gn', 'gen', gn_outdir])
    return 0

  def cmd_list(self):
    print '\n'.join(sorted(self._mbw.masters[self._options.master]))
    return 0

  def verbose_print_1(self, text):
    if self._options.verbosity >= 1:
      print '#' * 80
      print text

  def verbose_print_2(self, text):
    if self._options.verbosity >= 2:
      indent = ' ' * 2
      for l in text.splitlines():
        print indent + l

  def _call_cmd(self, args):
    self.verbose_print_1(' '.join(args))
    try:
      output = subprocess.check_output(
        args=args,
        stderr=subprocess.STDOUT,
      )
      self.verbose_print_2(output)
    except subprocess.CalledProcessError as e:
      self.verbose_print_2(e.output)
      raise

  def _find_work_dir(self, path):
    """Find the closest v8 root to `path`."""
    if os.path.exists(os.path.join(path, 'tools', 'dev', 'v8gen.py')):
      # Approximate the v8 root dir by a folder where this script exists
      # in the expected place.
      return path
    elif os.path.dirname(path) == path:
      raise Exception(
          'This appears to not be called from a recent v8 checkout')
    else:
      return self._find_work_dir(os.path.dirname(path))

  @property
  def _goma_dir(self):
    return os.path.normpath(os.environ.get('GOMA_DIR') or GOMA_DEFAULT)

  @property
  def _need_goma_dir(self):
    return self._goma_dir != GOMA_DEFAULT

  @property
  def _use_goma(self):
    if self._options.goma is None:
      # Auto-detect.
      return os.path.exists(self._goma_dir) and os.path.isdir(self._goma_dir)
    else:
      return self._options.goma

  @property
  def _goma_args(self):
    """Gn args for using goma."""
    # Specify goma args if we want to use goma and if goma isn't specified
    # via command line already. The command-line always has precedence over
    # any other specification.
    if (self._use_goma and
        not any(re.match(r'use_goma\s*=.*', x) for x in self._gn_args)):
      if self._need_goma_dir:
        return 'use_goma=true\ngoma_dir="%s"' % self._goma_dir
      else:
        return 'use_goma=true'
    else:
      return ''

  def _append_gn_args(self, type, gn_args_path, more_gn_args):
    """Append extra gn arguments to the generated args.gn file."""
    if not more_gn_args:
      return False
    self.verbose_print_1('Appending """\n%s\n""" to %s.' % (
        more_gn_args, os.path.abspath(gn_args_path)))
    with open(gn_args_path, 'a') as f:
      f.write('\n# Additional %s args:\n' % type)
      f.write(more_gn_args)
      f.write('\n')

    # Artificially increment modification time as our modifications happen too
    # fast. This makes sure that gn is properly rebuilding the ninja files.
    mtime = os.path.getmtime(gn_args_path) + 1
    with open(gn_args_path, 'a'):
      os.utime(gn_args_path, (mtime, mtime))

    return True

  def main(self):
    # Always operate relative to the base directory for better relative-path
    # handling. This script can be used in any v8 checkout.
    workdir = self._find_work_dir(os.getcwd())
    if workdir != os.getcwd():
      self.verbose_print_1('cd ' + workdir)
      os.chdir(workdir)

    # Initialize MB as a library.
    self._mbw = mb.MetaBuildWrapper()

    # TODO(machenbach): Factor out common methods independent of mb arguments.
    self._mbw.ParseArgs(['lookup', '-f', CONFIG])
    self._mbw.ReadConfigFile()

    if not self._options.master in self._mbw.masters:
      print '%s not found in %s\n' % (self._options.master, CONFIG)
      print 'Choose one of:\n%s\n' % (
          '\n'.join(sorted(self._mbw.masters.keys())))
      return 1

    return self._options.func()


if __name__ == "__main__":
  gen = GenerateGnArgs(sys.argv[1:])
  try:
    sys.exit(gen.main())
  except Exception:
    if gen._options.verbosity < 2:
      print ('\nHint: You can raise verbosity (-vv) to see the output of '
             'failed commands.\n')
    raise
