#!/usr/bin/env python
# Copyright 2015 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 logging
import os
import subprocess
import sys

_logger = logging.getLogger()
_root_path = os.path.realpath(os.path.dirname(__file__))

def _linux_out_dir(args):
  if args.debug:
      return os.path.join(_root_path, 'out/Debug')
  return os.path.join(_root_path, 'out/Release')

def _android_out_dir(args):
  if args.debug:
    return os.path.join(_root_path, 'out/android_Debug')
  return os.path.join(_root_path, 'out/android_Release')


def _init_logging(verbose_count):
  if verbose_count == 0:
    level = logging.WARNING
  elif verbose_count == 1:
    level = logging.INFO
  else:
    level = logging.DEBUG

  logging.basicConfig()
  _logger.setLevel(level)
  _logger.debug('Initialized logging: verbose_count=%d, level=%d' %
               (verbose_count, level))

def _run_gn(gn_args, out_dir):
  # TODO(jamesr): add '--check' to the args.
  command = ['gn', 'gen']
  command.append(out_dir)
  command.append('--args=%s' % ' '.join(gn_args))
  print 'Running %s ...' % (' '.join(command))
  return subprocess.call(command)

_goma_dir_str = 'goma_dir = '
_use_goma_str = 'use_goma = '

def _gn(args):
  _logger.debug('_gn()')

  gn_args = ['is_debug = ' + ('true' if args.debug else 'false')]

  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:
      gn_args.append(_goma_dir_str + '"' + goma_dir + '"')
      gn_args.append(_use_goma_str + 'true')
    elif args.goma and os.path.exists(goma_home_dir):
      gn_args.append(_goma_dir_str + '"' + goma_home_dir + '"')
      gn_args.append(_use_goma_str + 'true')

  retcode = _run_gn(gn_args, _linux_out_dir(args))
  if retcode != 0:
    return retcode
  gn_args.append('target_os="android"')
  gn_args.append('target_cpu="arm"')
  return _run_gn(gn_args, _android_out_dir(args))

def _run_build(out_dir):
  gn_file = os.path.join(out_dir, 'args.gn')
  use_goma = False
  with open(gn_file, 'r') as f:
    lines = f.readlines()
    for l in lines:
      if l.startswith(_goma_dir_str):
        use_goma = True
        local_goma_dir = l[len(_goma_dir_str)+1:len(l)-2]
        break
  _logger.info('use_goma = %s' % use_goma)
  if use_goma:
    print 'Ensuring goma (in %s) started ...' % local_goma_dir
    command = ['python',
               os.path.join(local_goma_dir, 'goma_ctl.py'),
               'ensure_start']
    retcode = subprocess.call(command)
    if retcode != 0:
      return retcode

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

# Unused argument - pylint: disable=W0613
def _build(args):
  _logger.debug('_build()')
  retcode = _run_build(_linux_out_dir(args))
  if retcode != 0:
    return retcode
  return _run_build(_android_out_dir(args))

# Unused argument - pylint: disable=W0613
def _test(args):
  _logger.debug('_test()')
  # TODO(jamesr): Run tests on android too
  out_dir = 'out/Release'
  return subprocess.call([os.path.join(out_dir, 'mojo_shell'),
      'mojo:network_service_apptests'])

def _upload(args):
  if args.debug:
    print "Only upload release binaries (for now)"
    return 1
  base_command = ['tools/upload_service.py',
                  '--linux-x64-binary-dir', _linux_out_dir(args),
                  '--android-arm-binary-dir', _android_out_dir(args)]
  if args.dry_run:
    base_command.append('--dry-run')
  _logger.info('Uploading network service binary')
  retcode = subprocess.call(base_command + ['--upload-symbols',
                                            'network_service'])
  if retcode != 0:
    return retcode
  _logger.info('Uploading network service apptests binary')
  return subprocess.call(base_command + ['network_service_apptests'])


def main():
  parser = argparse.ArgumentParser(
      description='Script to help build and upload monet')

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

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

  subparsers = parser.add_subparsers()

  gn_parser = subparsers.add_parser('gn', parents=[parent_parser],
      help='Run gn to generate build files')
  gn_parser.set_defaults(func=_gn)
  gn_parser.add_argument('--args', help='Specify extra args', default=None,
      dest='gn_args')
  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 network service apptests')
  test_parser.set_defaults(func=_test)

  upload_parser = subparsers.add_parser('upload', parents=[parent_parser],
      help='Upload already built binaries to Google Cloud Storage')
  upload_parser.add_argument('--dry-run', '-n',
      help='Dry run (prints what it would upload but does not actually upload)',
      action='store_true')
  upload_parser.set_defaults(func=_upload)

  args = parser.parse_args()
  _init_logging(args.verbose_count)
  return args.func(args)

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