#!/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', 'dartanalyzer'),
    os.path.join('tests', 'html', 'element_test.dart'),
    '--dart-sdk=sdk',
    '--show-package-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 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'],
  '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()
