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

import os
import re
import sys

import bot

GCS_BUCKET = 'gs://dart-cross-compiled-binaries'
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(SCRIPT_DIR, '..'))

import utils

CROSS_VM = r'cross-(arm)-vm-linux-(release)'
TARGET_VM = r'target-(arm)-vm-linux-(([0-9]+)-([0-9]+))?(release)'
GSUTIL = utils.GetBuildbotGSUtilPath()

def run(args):
  print 'Running: %s' % (' '.join(args))
  sys.stdout.flush()
  bot.RunProcess(args)

def tarball_name(arch, mode, revision):
  return 'cross_build_%s_%s_%s.tar.bz2' % (arch, mode, revision)

def record_names(name, arch, mode):
  return ('record_%s_%s_%s.json' % (name, arch, mode),
          'record_output_%s_%s_%s.json' % (name, arch, mode))

def cross_compiling_builder(arch, mode):
  build_py = os.path.join('tools', 'build.py')
  revision = os.environ['BUILDBOT_GOT_REVISION']
  tarball = tarball_name(arch, mode, revision)
  temporary_files = [tarball]
  bot.Clobber()
  try:
    num_run = int(os.environ['BUILDBOT_ANNOTATED_STEPS_RUN'])
    if num_run == 1:
      with bot.BuildStep('Build %s %s' % (arch, mode)):
        run([sys.executable, build_py,
             '-m%s' % mode, '--arch=%s' % arch, 'runtime'])

      with bot.BuildStep('Create build tarball'):
        run(['tar', '-cjf', tarball, '--exclude=**/obj',
             '--exclude=**/obj.host', '--exclude=**/obj.target',
             '--exclude=**/*analyzer*', 'out/', 'tools/testing/bin/'])

      with bot.BuildStep('Upload build tarball'):
        uri = "%s/%s" % (GCS_BUCKET, tarball)
        run([GSUTIL, 'cp', '-a', 'public-read', tarball, uri])

    elif num_run == 2:
      with bot.BuildStep('tests'):
        print "Please see the target device for results."
        print "We no longer record/replay tests."
    else:
      raise Exception("Invalid annotated steps run")
  finally:
    for path in temporary_files:
      if os.path.exists(path):
        os.remove(path)

def target_builder(arch, mode, total_shards, shard_index):
  test_py = os.path.join('tools', 'test.py')
  test_args = [sys.executable, test_py, '--progress=line', '--report',
               '--time', '--compiler=none', '--runtime=vm', '--write-debug-log',
               '--write-test-outcome-log', '--mode=' + mode, '--arch=' + arch,
               '--exclude-suite=pkg']
  if total_shards and shard_index:
    test_args.append('--shards=%s' % total_shards)
    test_args.append('--shard=%s' % shard_index)

  revision = os.environ['BUILDBOT_GOT_REVISION']
  tarball = tarball_name(arch, mode, revision)
  temporary_files = [tarball]
  bot.Clobber()
  try:
    with bot.BuildStep('Fetch build tarball'):
      run([GSUTIL, 'cp', "%s/%s" % (GCS_BUCKET, tarball), tarball])

    with bot.BuildStep('Unpack build tarball'):
      run(['tar', '-xjf', tarball])

    with bot.BuildStep('execute tests'):
      run(test_args)

    with bot.BuildStep('execute checked_tests'):
      run(test_args + ['--checked', '--append_logs'])
  finally:
    for path in temporary_files:
      if os.path.exists(path):
        os.remove(path)
    # We always clobber this to save disk on the arm board.
    bot.Clobber(force=True)

def main():
  name, is_buildbot = bot.GetBotName()

  cross_vm_pattern_match = re.match(CROSS_VM, name)
  target_vm_pattern_match = re.match(TARGET_VM, name)
  if cross_vm_pattern_match:
    arch = cross_vm_pattern_match.group(1)
    mode = cross_vm_pattern_match.group(2)
    cross_compiling_builder(arch, mode)
  elif target_vm_pattern_match:
    arch = target_vm_pattern_match.group(1)
    mode = target_vm_pattern_match.group(5)
    shard_index = target_vm_pattern_match.group(3)
    total_shards = target_vm_pattern_match.group(4)
    target_builder(arch, mode, total_shards, shard_index)
  else:
    raise Exception("Unknown builder name %s" % name)

if __name__ == '__main__':
  try:
    sys.exit(main())
  except OSError as e:
    sys.exit(e.errno)
