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

# This a simple script to make building/testing Mojo components easier.

import argparse
from copy import deepcopy
import os
import subprocess
import sys

from get_test_list import GetTestList
from mopy.config import Config
from mopy.paths import Paths
from mopy.gn import GNArgsForConfig, ParseGNConfig, CommandLineForGNArgs


def _args_to_config(args):
  # Default to host OS.
  target_os = None
  if args.android:
    target_os = Config.OS_ANDROID
  elif args.chromeos:
    target_os = Config.OS_CHROMEOS

  target_arch = args.target_arch

  additional_args = {}

  if 'clang' in args:
    additional_args['is_clang'] = args.clang

  if 'asan' in args and args.asan:
    additional_args['sanitizer'] = Config.SANITIZER_ASAN

  # Additional non-standard config entries:

  if 'goma' in args:
    goma_dir = os.environ.get('GOMA_DIR')
    goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma')
    if args.goma and goma_dir:
      additional_args['use_goma'] = True
      additional_args['goma_dir'] = goma_dir
    elif args.goma and os.path.exists(goma_home_dir):
      additional_args['use_goma'] = True
      additional_args['goma_dir'] = goma_home_dir
    else:
      additional_args['use_goma'] = False
      additional_args['goma_dir'] = None

  additional_args['use_nacl'] = args.nacl

  if 'dry_run' in args:
    additional_args['dry_run'] = args.dry_run

  if 'builder_name' in args:
    additional_args['builder_name'] = args.builder_name
  if 'build_number' in args:
    additional_args['build_number'] = args.build_number
  if 'master_name' in args:
    additional_args['master_name'] = args.master_name
  if 'test_results_server' in args:
    additional_args['test_results_server'] = args.test_results_server

  return Config(target_os=target_os, target_arch=target_arch,
                is_debug=args.debug, dcheck_always_on=args.dcheck_always_on,
                **additional_args)


def _get_out_dir(config):
  paths = Paths(config)
  return paths.SrcRelPath(paths.build_dir)


def sync(config):
  # pylint: disable=W0613
  return subprocess.call(['gclient', 'sync'])


def gn(config):
  command = ['gn', 'gen', '--check']

  gn_args = CommandLineForGNArgs(GNArgsForConfig(config))
  out_dir = _get_out_dir(config)
  command.append(out_dir)
  command.append('--args=%s' % ' '.join(gn_args))

  print 'Running %s %s ...' % (command[0],
                               ' '.join('\'%s\'' % x for x in command[1:]))
  return subprocess.call(command)


def build(config):
  out_dir = _get_out_dir(config)
  gn_args = ParseGNConfig(out_dir)
  print 'Building in %s ...' % out_dir
  if gn_args.get('use_goma'):
    # Use the configured goma directory.
    local_goma_dir = gn_args.get('goma_dir')
    print 'Ensuring goma (in %s) started ...' % local_goma_dir
    command = ['python',
               os.path.join(local_goma_dir, 'goma_ctl.py'),
               'ensure_start']
    exit_code = subprocess.call(command)
    if exit_code:
      return exit_code

    return subprocess.call(['ninja', '-j', '1000', '-l', '100', '-C', out_dir])
  else:
    return subprocess.call(['ninja', '-C', out_dir])


def _run_tests(config, test_types):
  """Runs the tests of the given type(s) for the given config."""

  assert isinstance(test_types, list)
  config = deepcopy(config)
  config.values['test_types'] = test_types

  test_list = GetTestList(config)
  dry_run = config.values.get('dry_run')
  final_exit_code = 0
  for entry in test_list:
    print 'Running: %s' % entry['name']
    print 'Command: %s' % entry['command']
    if dry_run:
      continue

    exit_code = subprocess.call(entry['command'])
    if not final_exit_code:
      final_exit_code = exit_code
  return final_exit_code


def test(config):
  return _run_tests(config, [Config.TEST_TYPE_DEFAULT])


def perftest(config):
  return _run_tests(config, [Config.TEST_TYPE_PERF])


def pytest(config):
  return _run_tests(config, ['python'])


def darttest(config):
  return _run_tests(config, ['dart'])


def nacltest(config):
  return _run_tests(config, ['nacl'])


def main():
  os.chdir(Paths().src_root)

  parser = argparse.ArgumentParser(description='A script to make building'
      '/testing Mojo components easier.')

  parent_parser = argparse.ArgumentParser(add_help=False)
  parent_parser.add_argument('--asan', help='Use Address Sanitizer',
                             action='store_true')
  parent_parser.add_argument('--dcheck_always_on',
                             help='DCHECK and MOJO_DCHECK are fatal even in '
                             'release builds',
                             action='store_true')

  debug_group = parent_parser.add_mutually_exclusive_group()
  debug_group.add_argument('--debug', help='Debug build (default)',
                           default=True, action='store_true')
  debug_group.add_argument('--release', help='Release build', default=False,
                           dest='debug', action='store_false')

  os_group = parent_parser.add_mutually_exclusive_group()
  os_group.add_argument('--android', help='Build for Android',
                        action='store_true')
  os_group.add_argument('--chromeos', help='Build for ChromeOS',
                        action='store_true')

  parent_parser.add_argument('--target-arch',
                             help='CPU architecture to build for.',
                             choices=['x64', 'x86', 'arm'])

  parent_parser.add_argument('--nacl', help='Add in NaCl', default=False,
                             action='store_true')

  subparsers = parser.add_subparsers()

  sync_parser = subparsers.add_parser('sync', parents=[parent_parser],
      help='Sync using gclient (does not run gn).')
  sync_parser.set_defaults(func=sync)

  gn_parser = subparsers.add_parser('gn', parents=[parent_parser],
                                    help='Run gn for mojo (does not sync).')
  gn_parser.set_defaults(func=gn)
  clang_group = gn_parser.add_mutually_exclusive_group()
  clang_group.add_argument('--clang', help='Use Clang (default)', default=None,
                           action='store_true')
  clang_group.add_argument('--gcc', help='Use GCC',
                           dest='clang', action='store_false')
  goma_group = gn_parser.add_mutually_exclusive_group()
  goma_group.add_argument('--goma',
                          help='Use Goma (if $GOMA_DIR is set or $HOME/goma '
                               'exists; default)',
                          default=True,
                          action='store_true')
  goma_group.add_argument('--no-goma', help='Don\'t use Goma', default=False,
                          dest='goma', action='store_false')

  build_parser = subparsers.add_parser('build', parents=[parent_parser],
                                       help='Build')
  build_parser.set_defaults(func=build)

  test_parser = subparsers.add_parser('test', parents=[parent_parser],
                                      help='Run unit tests (does not build).')
  test_parser.set_defaults(func=test)
  test_parser.add_argument('--dry-run',
                           help='Print instead of executing commands',
                           default=False, action='store_true')

  perftest_parser = subparsers.add_parser('perftest', parents=[parent_parser],
      help='Run perf tests (does not build).')
  perftest_parser.set_defaults(func=perftest)

  pytest_parser = subparsers.add_parser('pytest', parents=[parent_parser],
      help='Run Python unit tests (does not build).')
  pytest_parser.set_defaults(func=pytest)

  darttest_parser = subparsers.add_parser('darttest', parents=[parent_parser],
      help='Run Dart unit tests (does not build).')
  darttest_parser.set_defaults(func=darttest)

  nacltest_parser = subparsers.add_parser('nacltest', parents=[parent_parser],
      help='Run NaCl unit tests (does not build).')
  nacltest_parser.set_defaults(func=nacltest)

  args = parser.parse_args()
  config = _args_to_config(args)
  return args.func(config)


if __name__ == '__main__':
  sys.exit(main())
