#!/usr/bin/python

# Copyright (c) 2012, 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.

"""
Dart2js buildbot steps

Runs tests for the  dart2js compiler.
"""

import os
import platform
import re
import shutil
import socket
import subprocess
import sys

import bot

DARTIUM_BUILDER = r'none-dartium-(linux|mac|windows)'
DART2JS_BUILDER = (
    r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?(-(x64))?-?(\d*)-?(\d*)')
DART2JS_FULL_BUILDER = r'dart2js-full-(linux|mac|windows)(-checked)?(-minified)?-(\d+)-(\d+)'
WEB_BUILDER = (
    r'dart2js-(ie9|ie10|ff|safari|chrome|chromeOnAndroid|opera|drt)-(win7|win8|mac10\.8|mac10\.7|linux)(-(all|html))?(-(csp))?(-(\d+)-(\d+))?')

DART2JS_FULL_CONFIGURATIONS = {
  'linux' : [ ],
  'mac' : [ ],
  'windows' : [
    {'runtime' : 'ie9'},
    {'runtime' : 'ie9', 'additional_flags' : ['--checked']},
  ],
}


def GetBuildInfo(builder_name, is_buildbot):
  """Returns a BuildInfo object for the current buildbot based on the
     name of the builder.
  """
  compiler = None
  runtime = None
  mode = None
  system = None
  checked = False
  host_checked = False
  minified = False
  shard_index = None
  total_shards = None
  test_set = None
  csp = None
  arch = None
  dart2js_full = False

  dart2js_pattern = re.match(DART2JS_BUILDER, builder_name)
  dart2js_full_pattern = re.match(DART2JS_FULL_BUILDER, builder_name)
  web_pattern = re.match(WEB_BUILDER, builder_name)
  dartium_pattern = re.match(DARTIUM_BUILDER, builder_name)

  if web_pattern:
    compiler = 'dart2js'
    runtime = web_pattern.group(1)
    system = web_pattern.group(2)
    mode = 'release'
    test_set = web_pattern.group(4)
    if web_pattern.group(6) == 'csp':
      csp = True
    shard_index = web_pattern.group(8)
    total_shards = web_pattern.group(9)
  elif dart2js_full_pattern:
    mode = 'release'
    compiler = 'dart2js'
    dart2js_full = True
    system = dart2js_full_pattern.group(1)
    if dart2js_full_pattern.group(2):
      checked = True
    if dart2js_full_pattern.group(3):
      minified = True
    shard_index = dart2js_full_pattern.group(4)
    total_shards = dart2js_full_pattern.group(5)
  elif dart2js_pattern:
    compiler = 'dart2js'
    system = dart2js_pattern.group(1)
    runtime = 'd8'
    arch = 'ia32'
    if dart2js_pattern.group(3) == 'jsshell':
      runtime = 'jsshell'
    mode = dart2js_pattern.group(4)
    # The valid naming parts for checked and host-checked are:
    # Empty: checked=False, host_checked=False
    # -checked: checked=True, host_checked=False
    # -host-checked: checked=False, host_checked=True
    # -checked-host-checked: checked=True, host_checked=True
    if dart2js_pattern.group(6) == 'checked':
      checked = True
    if dart2js_pattern.group(6) == 'host-checked':
      host_checked = True
    if dart2js_pattern.group(8) == 'host-checked':
      host_checked = True
    if dart2js_pattern.group(10) == 'minified':
      minified = True
    if dart2js_pattern.group(12) == 'x64':
      arch = 'x64'
    shard_index = dart2js_pattern.group(13)
    total_shards = dart2js_pattern.group(14)
  elif dartium_pattern:
    compiler = 'none'
    runtime = 'dartium'
    mode = 'release'
    system = dartium_pattern.group(1)
  else :
    return None

  # We have both win7 and win8 bots, functionality is the same.
  if system.startswith('win'):
    system = 'windows'

  # We have both 10.8 and 10.7 bots, functionality is the same.
  if system == 'mac10.8' or system == 'mac10.7':
    system = 'mac'

  if (system == 'windows' and platform.system() != 'Windows') or (
      system == 'mac' and platform.system() != 'Darwin') or (
      system == 'linux' and platform.system() != 'Linux'):
    print ('Error: You cannot emulate a buildbot with a platform different '
        'from your own.')
    return None
  return bot.BuildInfo(compiler, runtime, mode, system, checked, host_checked,
                       minified, shard_index, total_shards, is_buildbot,
                       test_set, csp, arch, dart2js_full)


def NeedsXterm(compiler, runtime):
  return runtime in ['ie9', 'ie10', 'chrome', 'safari', 'opera', 'ff', 'drt',
                     'dartium']


def TestStepName(name, flags):
  # Filter out flags with '=' as this breaks the /stats feature of the
  # build bot.
  flags = [x for x in flags if not '=' in x]
  return ('%s tests %s' % (name, ' '.join(flags))).strip()


IsFirstTestStepCall = True
def TestStep(name, mode, system, compiler, runtime, targets, flags, arch):
  step_name = TestStepName(name, flags)
  with bot.BuildStep(step_name, swallow_error=True):
    sys.stdout.flush()
    if NeedsXterm(compiler, runtime) and system == 'linux':
      cmd = ['xvfb-run', '-a']
    else:
      cmd = []

    user_test = os.environ.get('USER_TEST', 'no')

    cmd.extend([sys.executable,
                os.path.join(os.curdir, 'tools', 'test.py'),
                '--step_name=' + step_name,
                '--mode=' + mode,
                '--compiler=' + compiler,
                '--runtime=' + runtime,
                '--arch=' + arch,
                '--time',
                '--use-sdk',
                '--report',
                '--write-debug-log',
                '--write-test-outcome-log'])

    if user_test == 'yes':
      cmd.append('--progress=color')
    else:
      cmd.extend(['--progress=buildbot', '-v'])

    if runtime == 'safari':
      cmd.append('--clear_safari_cache')

    global IsFirstTestStepCall
    if IsFirstTestStepCall:
      IsFirstTestStepCall = False
    else:
      cmd.append('--append_logs')

    if flags:
      cmd.extend(flags)
    cmd.extend(targets)

    print 'Running: %s' % (' '.join(map(lambda arg: '"%s"' % arg, cmd)))
    sys.stdout.flush()
    bot.RunProcess(cmd)


def TestCompiler(runtime, mode, system, flags, is_buildbot, arch,
                 compiler=None, dart2js_full=False):
  """ test the compiler.
   Args:
     - runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo
     - mode: either 'debug' or 'release'
     - system: either 'linux', 'mac', 'windows'
     - flags: extra flags to pass to test.dart
     - is_buildbot: true if we are running on a real buildbot instead of
       emulating one.
     - arch: The architecture to run on.
     - compiler: The compiler to use for test.py (default is 'dart2js').
  """

  if not compiler:
    compiler = 'dart2js'

  def GetPath(runtime):
    """ Helper to get the path to the Chrome or Firefox executable for a
    particular platform on the buildbot. Throws a KeyError if runtime is not
    either 'chrome' or 'ff'."""
    if system == 'mac':
      partDict = {'chrome': 'Google\\ Chrome', 'ff': 'Firefox'}
      mac_path = '/Applications/%s.app/Contents/MacOS/%s'
      path_dict = {'chrome': mac_path % (partDict[runtime], partDict[runtime]),
          'ff': mac_path % (partDict[runtime], partDict[runtime].lower())}
    elif system == 'linux':
      path_dict = {'ff': 'firefox', 'chrome': 'google-chrome'}
    else:
      # Windows.
      path_dict = {'ff': os.path.join('C:/', 'Program Files (x86)',
          'Mozilla Firefox', 'firefox.exe'),
          'chrome': os.path.join('C:/', 'Users', 'chrome-bot', 'AppData',
          'Local', 'Google', 'Chrome', 'Application', 'chrome.exe')}
    return path_dict[runtime]

  if (compiler == 'dart2js' and (runtime == 'ff' or runtime == 'chrome')
      and is_buildbot):
    # Print out browser version numbers if we're running on the buildbot (where
    # we know the paths to these browser installations).
    version_query_string = '"%s" --version' % GetPath(runtime)
    if runtime == 'ff' and system == 'windows':
      version_query_string += '| more'
    elif runtime == 'chrome' and system == 'windows':
      version_query_string = ('''reg query "HKCU\\Software\\Microsoft\\''' +
          '''Windows\\CurrentVersion\\Uninstall\\Google Chrome" /v Version''')
    p = subprocess.Popen(version_query_string,
        stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    output, stderr = p.communicate()
    output = output.split()
    try:
      print 'Version of %s: %s' % (runtime, output[-1])
    except IndexError:
      # Failed to obtain version information. Continue running tests.
      pass

  if runtime == 'd8':
    # The dart2js compiler isn't self-hosted (yet) so we run its
    # unit tests on the VM. We avoid doing this on the builders
    # that run the browser tests to cut down on the cycle time.
    unit_test_flags = [flag for flag in flags if flag.startswith('--shard')]
    # Run the unit tests in checked mode (the VM's checked mode).
    unit_test_flags.append('--checked')
    TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'],
             unit_test_flags, arch)

  if compiler == 'dart2js' and system == 'windows' and runtime == 'ie10':
    TestStep("%s-%s" % (compiler, runtime), mode, system, compiler, runtime,
             ['html'], flags, arch)
  else:
    # Run the default set of test suites.
    TestStep("%s-%s" % (compiler, runtime), mode, system, compiler,
             runtime, [], flags, arch)

    if compiler == 'dart2js':
      # TODO(kasperl): Consider running peg and css tests too.
      extras = ['dart2js_extra', 'dart2js_native']
      extras_flags = flags
      if (system == 'linux'
          and runtime == 'd8'
          and not '--host-checked' in extras_flags):
        # Run the extra tests in checked mode, but only on linux/d8.
        # Other systems have less resources and tend to time out.
        extras_flags = extras_flags + ['--host-checked']
      TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
               extras_flags, arch)

def GetHasHardCodedCheckedMode(build_info):
  # TODO(ricow): We currently run checked mode tests on chrome on linux and
  # on the slow (all) IE windows bots. This is a hack and we should use the
  # normal sharding and checked splitting functionality when we get more
  # vms for testing this.
  if (build_info.system == 'linux' and build_info.runtime == 'drt'):
    return True
  if build_info.runtime.startswith('ie') and build_info.test_set == 'all':
    return True
  return False


def GetLocalIPAddress():
  hostname = socket.gethostname()
  # '$ host chromeperf02' results for example in
  # 'chromeperf02.perf.chromium.org has address 172.22.28.55'
  output = subprocess.check_output(["host", hostname])
  match = re.match(r'.*\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s+.*', output)
  if not match:
    raise Exception("Could not determine local ip address "
                    "(hostname: '%s', host command output: '%s')."
                    % (hostname, output))
  return match.group(1)

def AddAndroidToolsToPath():
  par_dir = os.path.pardir
  join = os.path.join

  dart_dir = join(os.path.dirname(__file__), par_dir, par_dir)
  android_sdk = join(dart_dir, 'third_party', 'android_tools', 'sdk')
  tools_dir = os.path.abspath(join(android_sdk, 'tools'))
  platform_tools_dir = os.path.abspath(join(android_sdk, 'platform-tools'))
  os.environ['PATH'] = os.pathsep.join(
      [os.environ['PATH'], tools_dir, platform_tools_dir])

def RunCompilerTests(build_info):
  test_flags = []
  if build_info.shard_index:
    test_flags = ['--shards=%s' % build_info.total_shards,
                  '--shard=%s' % build_info.shard_index]
  if build_info.checked: test_flags += ['--checked']
  if build_info.minified: test_flags += ['--minified']
  if build_info.host_checked: test_flags += ['--host-checked']

  if build_info.dart2js_full:
    compiler = build_info.compiler
    assert compiler == 'dart2js'
    system = build_info.system
    arch = build_info.arch
    mode = build_info.mode
    is_buildbot = build_info.is_buildbot
    for configuration in DART2JS_FULL_CONFIGURATIONS[system]:
      additional_flags = configuration.get('additional_flags', [])
      TestCompiler(configuration['runtime'], mode, system,
                   test_flags + additional_flags, is_buildbot, arch,
                   compiler=compiler, dart2js_full=True)
  else:
    if build_info.csp: test_flags += ['--csp']

    if build_info.runtime == 'chromeOnAndroid':
      test_flags.append('--local_ip=%s' % GetLocalIPAddress())
      # test.py expects the android tools directories to be in PATH
      # (they contain for example 'adb')
      AddAndroidToolsToPath()

    TestCompiler(build_info.runtime, build_info.mode, build_info.system,
                 list(test_flags), build_info.is_buildbot,
                 build_info.arch, compiler=build_info.compiler)

    # See comment in GetHasHardCodedCheckedMode, this is a hack.
    if (GetHasHardCodedCheckedMode(build_info)):
      TestCompiler(build_info.runtime, build_info.mode, build_info.system,
                   test_flags + ['--checked'], build_info.is_buildbot,
                   build_info.arch,  compiler=build_info.compiler)


def BuildCompiler(build_info):
  """
  Builds the SDK.

  - build_info: the buildInfo object, containing information about what sort of
      build and test to be run.
  """
  with bot.BuildStep('Build SDK'):
    args = [sys.executable, './tools/build.py', '--mode=' + build_info.mode,
            '--arch=' + build_info.arch, 'dart2js_bot']
    print 'Build SDK and d8: %s' % (' '.join(args))
    bot.RunProcess(args)


if __name__ == '__main__':
  bot.RunBot(GetBuildInfo, RunCompilerTests, build_step=BuildCompiler)
