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

  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']))
    exit_code = subprocess.call(entry['command'])
    _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'])

  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())
