#!/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.

"""A simple script to make building/testing Mojo components easier."""

import argparse
from copy import deepcopy
import logging
from multiprocessing import cpu_count
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
from mopy.log import InitLogging


_logger = logging.getLogger()
_verbose_count = 0


def _args_to_config(args):
  # Default to host OS.
  target_os = None
  if args.android:
    target_os = Config.OS_ANDROID
  elif args.ios:
    target_os = Config.OS_IOS
  elif args.fnl:
    target_os = Config.OS_FNL

  target_cpu = args.target_cpu

  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

  if 'nacl' in args:
    additional_args['use_nacl'] = args.nacl

  if not ('asan' in args and args.asan):
    go_dir = os.path.join(Paths().src_root, 'third_party', 'go', 'tool')
    if args.android:
      additional_args['mojo_use_go'] = True
      additional_args['go_build_tool'] = os.path.join(
          go_dir, 'android_arm', 'bin', 'go')
    elif target_os is None and Config.GetHostOS() == Config.OS_LINUX:
      additional_args['mojo_use_go'] = True
      additional_args['go_build_tool'] = os.path.join(
          go_dir, 'linux_amd64', 'bin', 'go')

  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

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

  is_debug = args.debug and not args.official

  if 'target_sysroot' in args and args.target_sysroot:
    additional_args['target_sysroot'] = os.path.abspath(args.target_sysroot)

  if 'toolchain_prefix' in args and args.toolchain_prefix:
    additional_args['toolchain_prefix'] = args.toolchain_prefix

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

  additional_args['boringssl_path'] = Paths().boringssl_path

  return Config(target_os=target_os, target_cpu=target_cpu,
                is_debug=is_debug, is_official_build=args.official,
                dcheck_always_on=args.dcheck_always_on,
                is_simulator=args.simulator, **additional_args)


def _get_out_dir(config):
  """Gets the build output directory (e.g., out/Debug), relative to src, for the
  given config."""

  paths = Paths(config)
  return paths.SrcRelPath(paths.build_dir)


def _sync(config):  # pylint: disable=W0613
  """Runs gclient sync for the given config."""

  _logger.debug('_sync()')
  return subprocess.call(['gclient', 'sync'])


def _gn(config):
  """Runs gn gen for the given config."""

  _logger.debug('_gn()')

  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):
  """Builds for the given config."""

  _logger.debug('_build()')

  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

    # Goma allows us to run many more jobs in parallel, say 32 per core/thread
    # (= 1024 on a 16-core, 32-thread Z620). Limit the load average to 4 per
    # core/thread (= 128 on said Z620).
    jobs = cpu_count() * 32
    limit = cpu_count() * 4
    return subprocess.call(['ninja', '-j', str(jobs), '-l', str(limit),
                            '-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, verbose_count=_verbose_count)
  dry_run = config.values.get('dry_run')
  final_exit_code = 0
  failure_list = []
  for entry in test_list:
    print 'Running: %s' % entry['name']
    print 'Command: %s' % ' '.join(entry['command'])
    if dry_run:
      continue

    _logger.info('Starting: %s' % ' '.join(entry['command']))
    env = os.environ
    if 'env' in entry and entry['env'] is not None:
      env.update(entry['env'])
    exit_code = subprocess.call(entry['command'], env=env)
    _logger.info('Completed: %s' % ' '.join(entry['command']))
    if exit_code:
      if not final_exit_code:
        final_exit_code = exit_code
      failure_list.append(entry['name'])

  print 72 * '='
  print 'SUMMARY:',
  if dry_run:
    print 'Dry run: no tests run'
  elif not failure_list:
    assert not final_exit_code
    print 'All tests passed'
  else:
    assert final_exit_code
    print 'The following had failures:', ', '.join(failure_list)

  return final_exit_code


def _test(config):
  _logger.debug('_test()')
  return _run_tests(config, [Config.TEST_TYPE_DEFAULT])


def _perftest(config):
  _logger.debug('_perftest()')
  return _run_tests(config, [Config.TEST_TYPE_PERF])


def _pytest(config):
  _logger.debug('_pytest()')
  return _run_tests(config, ['python'])

def _analyzedart(config):
  _logger.debug('_analyzedart()')
  command = ['python']
  build_dir = _get_out_dir(config)
  command.append(os.path.join("mojo",
                              "public",
                              "tools",
                              "dart_pkg_static_analysis.py"))
  command.append("--dart-pkg-dir=" + os.path.join(build_dir, "gen", "dart-pkg"))
  command.append("--dart-sdk=" + os.path.join("third_party",
                                              "dart-sdk", "dart-sdk"))
  command.append("--package-root=" + os.path.join(build_dir,
                                                  "gen",
                                                  "dart-pkg",
                                                  "packages"))
  if config.values.get('package_name'):
    command.append(config.values.get('package_name'))
  print 'Running %s %s ...' % (command[0],
                               ' '.join('\'%s\'' % x for x in command[1:]))
  return subprocess.call(command)

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('--verbose',
                             help='Be verbose (multiple times for more)',
                             default=0, dest='verbose_count', action='count')

  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')
  # The official build is a release build suitable for distribution, with a
  # different package name.
  debug_group.add_argument('--official', help='Official build', default=False,
                           dest='official', action='store_true')

  os_group = parent_parser.add_mutually_exclusive_group()
  os_group.add_argument('--android', help='Build for Android',
                        action='store_true')
  os_group.add_argument('--ios', help='Build for iOS',
                        action='store_true')
  os_group.add_argument('--fnl', help='Build for FNL',
                        action='store_true')

  parent_parser.add_argument('--simulator',
                             help='Build for a simulator of the target',
                             action='store_true')

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

  parent_parser.add_argument('--target-sysroot',
                             help='Location of sysroot for target',
                             default='',
                             dest='target_sysroot')

  parent_parser.add_argument('--toolchain-prefix',
                             help='Toolchain prefix',
                             default='',
                             dest='toolchain_prefix')

  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)
  gn_parser.add_argument('--args', help='Specify extra args',
                         default=None, dest='gn_args')
  # Note: no default, if nothing is specified on the command line GN decides.
  gn_parser.add_argument('--nacl', help='Add in NaCl', action='store_true',
                         default=argparse.SUPPRESS)
  gn_parser.add_argument('--no-nacl', help='Remove NaCl', action='store_false',
                         default=argparse.SUPPRESS, dest='nacl')

  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)

  analyze_dart_parser = subparsers.add_parser('analyze-dart',
      parents=[parent_parser],
      help='Run the dart analyzer (does not build.')
  analyze_dart_parser.add_argument('package_name', nargs='?', default=None)
  analyze_dart_parser.set_defaults(func=_analyzedart)

  args = parser.parse_args()
  global _verbose_count
  _verbose_count = args.verbose_count
  InitLogging(_verbose_count)

  if args.simulator and not args.ios:
    sys.exit("Currently, the simulator target is only configured for iOS")

  return args.func(_args_to_config(args))


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