#!/usr/bin/python

# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# A script which makes it easy to execute common DOM-related tasks

import os
import subprocess
import sys
from sys import argv

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import utils

dart_out_dir = utils.GetBuildRoot(utils.GuessOS(), 'release', 'ia32')
if utils.IsWindows():
  dart_bin = os.path.join(dart_out_dir, 'dart.exe')
else:
  dart_bin = os.path.join(dart_out_dir, 'dart')

dart_dir = os.path.abspath(os.path.join(
    os.path.dirname(os.path.realpath(__file__)),
    os.path.pardir, os.path.pardir))

def help():
  print('Helper script to make it easy to perform common tasks encountered '
     'during the life of a Dart DOM developer.\n'
     '\n'
     'For example, to re-generate DOM classes then run a specific test:\n'
     '  dom.py gen test_drt html/element_test\n'
     '\n'
     'Or re-generate DOM classes and run the Dart analyzer:\n'
     '  dom.py gen analyze\n')
  print('Commands: ')
  for cmd in sorted(commands.keys()):
    print('\t%s - %s' % (cmd, commands[cmd][1]))

def analyze():
  ''' Runs the dart analyzer. '''
  return call([
    os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart_analyzer'),
    os.path.join('tests', 'html', 'element_test.dart'),
    '--dart-sdk', 'sdk',
    '--show-sdk-warnings',
  ])

def build():
  ''' Builds the Dart binary '''
  return call([
    os.path.join('tools', 'build.py'),
    '--mode=release',
    '--arch=ia32',
    'runtime',
  ])

def dart2js():
  compile_dart2js(argv.pop(0), True)

def dartc():
  return call([
    os.path.join('tools', 'test.py'),
    '-m',
    'release',
    '-c',
    'dartc',
    '-r',
    'none'
  ])

def docs():
  return call([
    os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart'),
    '--package-root=%s' % os.path.join(dart_out_dir, 'packages/'),
    os.path.join('tools', 'dom', 'docs', 'bin', 'docs.dart'),
  ])

def test_docs():
  return call([
    os.path.join('tools', 'test.py'),
    '--mode=release',
    '--checked',
    'docs'
  ])

def compile_dart2js(dart_file, checked):
  out_file = dart_file + '.js'
  dart2js_path = os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart2js')
  args = [
    dart2js_path,
    dart_file,
    '--library-root=sdk/',
    '--disallow-unsafe-eval',
    '-o%s' % out_file
  ]
  if checked:
    args.append('--checked')

  call(args)
  return out_file

def gen():
  os.chdir(os.path.join('tools', 'dom', 'scripts'))
  result = call([os.path.join(os.getcwd(), 'dartdomgenerator.py'),
      '--rebuild', '--parallel', '--systems=htmldart2js,htmldartium'])
  os.chdir(os.path.join('..', '..', '..'))
  return result

def http_server():
  print('Browse tests at '
      '\033[94mhttp://localhost:5400/root_build/generated_tests/\033[0m')
  return call([
    utils.DartBinary(),
    os.path.join('tools', 'testing', 'dart', 'http_server.dart'),
    '--port=5400',
    '--crossOriginPort=5401',
    '--network=0.0.0.0',
    '--build-directory=%s' % os.path.join('out', 'ReleaseIA32')
  ])

def size_check():
  ''' Displays the dart2js size of swarm. '''
  dart_file = os.path.join('samples', 'swarm', 'swarm.dart')
  out_file = compile_dart2js(dart_file, False)

  return call([
    'du',
    '-kh',
    '--apparent-size',
    out_file,
  ])

  os.remove(out_file)
  os.remove(out_file + '.deps')
  os.remove(out_file + '.map')

def test_ff():
  test_dart2js('ff', argv)

def test_drt():
  test_dart2js('drt', argv)

def test_chrome():
  test_dart2js('chrome', argv)

def test_dart2js(browser, argv):
  cmd = [
    os.path.join('tools', 'test.py'),
    '-c', 'dart2js',
    '-r', browser,
    '--mode=release',
    '--checked',
    '--arch=ia32',
    '-v',
  ]
  if argv:
    cmd.append(argv.pop(0))
  else:
    print(
        'Test commands should be followed by tests to run. Defaulting to html')
    cmd.append('html')
  return call(cmd)

def call(args):
  print ' '.join(args)
  pipe = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  output, error = pipe.communicate()
  if output:
    print output
  if error:
    print error
  return pipe.returncode

commands = {
  'analyze': [analyze, 'Run the dart analyzer'],
  'build': [build, 'Build dart in release mode'],
  'dart2js': [dart2js, 'Run dart2js on the .dart file specified'],
  'dartc': [dartc, 'Runs dartc in release mode'],
  'docs': [docs, 'Generates docs.json'],
  'gen': [gen, 'Re-generate DOM generated files (run go.sh)'],
  'size_check': [size_check, 'Check the size of dart2js compiled Swarm'],
  'test_docs': [test_docs, 'Tests docs.dart'],
  'test_chrome': [test_chrome, 'Run tests in checked mode in Chrome.\n'
      '\t\tOptionally provide name of test to run.'],
  # TODO(antonm): fix option name.
  'test_drt': [test_drt, 'Run tests in checked mode in content shell.\n'
      '\t\tOptionally provide name of test to run.'],
  'test_ff': [test_ff, 'Run tests in checked mode in Firefox.\n'
      '\t\tOptionally provide name of test to run.'],
  'http_server': [http_server, 'Starts the testing server for manually '
      'running browser tests.'],
}

def main():
  success = True
  argv.pop(0)

  if not argv:
    help()
    success = False

  while (argv):
    # Make sure that we're always rooted in the dart root folder.
    os.chdir(dart_dir)
    command = argv.pop(0)

    if not command in commands:
      help();
      success = False
      break
    returncode = commands[command][0]()
    success = success and not bool(returncode)

  sys.exit(not success)

if __name__ == '__main__':
  main()
