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

"""
Shared code for use in the buildbot scripts.
"""

import optparse
import os
from os.path import abspath
from os.path import dirname
import subprocess
import sys

DART_PATH = dirname(dirname(dirname(abspath(__file__))))

BUILDER_NAME = 'BUILDBOT_BUILDERNAME'
BUILDER_CLOBBER = 'BUILDBOT_CLOBBER'


class BuildInfo(object):
  """
  Encapsulation of build information.

  - compiler: None, 'dart2dart' or 'dart2js'
  - runtime: 'd8', 'ie', 'ff', 'safari', 'chrome', 'opera', or None.
  - mode: 'debug' or 'release'.
  - system: 'linux', 'mac', or 'win7'.
  - checked: True if we should run in checked mode, otherwise False.
  - host_checked: True if we should run in host checked mode, otherwise False.
  - minified: True if we should minify the code, otherwise False
  - shard_index: The shard we are running, None when not specified.
  - total_shards: The total number of shards, None when not specified.
  - is_buildbot: True if we are on a buildbot (or emulating it).
  - test_set: Specification of a non standard test set or None.
  - csp: This is using csp when running
  - arch: The architecture to build on.
  - dart2js_full: Boolean indicating whether this builder will run dart2js
    on several different runtimes.
  - builder_tag: A tag indicating a special builder setup.
  """
  def __init__(self, compiler, runtime, mode, system, checked=False,
               host_checked=False, minified=False, shard_index=None,
               total_shards=None, is_buildbot=False, test_set=None,
               csp=None, arch=None, dart2js_full=False, builder_tag=None):
    self.compiler = compiler
    self.runtime = runtime
    self.mode = mode
    self.system = system
    self.checked = checked
    self.host_checked = host_checked
    self.minified = minified
    self.shard_index = shard_index
    self.total_shards = total_shards
    self.is_buildbot = is_buildbot
    self.test_set = test_set
    self.csp = csp
    self.dart2js_full = dart2js_full
    self.builder_tag = builder_tag
    if (arch == None):
      self.arch = 'ia32'
    else:
      self.arch = arch

  def PrintBuildInfo(self):
    shard_description = ""
    if self.shard_index:
      shard_description = " shard %s of %s" % (self.shard_index,
                                               self.total_shards)
    print ("compiler: %s, runtime: %s mode: %s, system: %s,"
           " checked: %s, host-checked: %s, minified: %s, test-set: %s"
           " arch: %s%s"
           ) % (self.compiler, self.runtime, self.mode, self.system,
                self.checked, self.host_checked, self.minified, self.test_set,
                self.arch, shard_description)


class BuildStep(object):
  """
  A context manager for handling build steps.

  When the context manager is entered, it prints the "@@@BUILD_STEP __@@@"
  message. If it exits from an error being raised it displays the
  "@@@STEP_FAILURE@@@" message.

  If swallow_error is True, then this will catch and discard any OSError that
  is thrown. This lets you run later BuildSteps if the current one fails.
  """
  def __init__(self, name, swallow_error=False):
    self.name = name
    self.swallow_error = swallow_error

  def __enter__(self):
    print '@@@BUILD_STEP %s@@@' % self.name
    sys.stdout.flush()

  def __exit__(self, type, value, traceback):
    if value:
      print '@@@STEP_FAILURE@@@'
      sys.stdout.flush()
      if self.swallow_error and isinstance(value, OSError):
        return True


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

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


def RunBot(parse_name, custom_steps, build_step=BuildSDK):
  """
  The main function for running a buildbot.

  A buildbot script should invoke this once. The parse_name function will be
  called with the name of the buildbot and should return an instance of
  BuildInfo. This function will then set up the bot, build the SDK etc. When
  that's done, it will call custom_steps, passing in the BuildInfo object.

  In that, you can perform any bot-specific build steps.

  This function will not return. It will call sys.exit() with an appropriate
  exit code.
  """
  if len(sys.argv) == 0:
    print 'Script pathname not known, giving up.'
    sys.exit(1)

  name, is_buildbot = GetBotName()
  build_info = parse_name(name, is_buildbot)
  if not build_info:
    print 'Could not handle unfamiliar bot name "%s".' % name
    sys.exit(1)

  # Print out the buildinfo for easy debugging.
  build_info.PrintBuildInfo()

  # Make sure we are in the dart directory
  os.chdir(DART_PATH)

  try:
    Clobber()
    if build_step: 
      build_step(build_info)

    custom_steps(build_info)
  except OSError as e:
    sys.exit(e.errno)

  sys.exit(0)


def GetBotName():
  """
  Gets the name of the current buildbot.

  Returns a tuple of the buildbot name and a flag to indicate if we are actually
  a buildbot (True), or just a user pretending to be one (False).
  """
  # For testing the bot locally, allow the user to pass in a buildbot name.
  parser = optparse.OptionParser()
  parser.add_option('-n', '--name', dest='name', help='The name of the build'
      'bot you would like to emulate (ex: vm-mac-debug)', default=None)
  args, _ = parser.parse_args()

  if args.name:
    return args.name, False

  name = os.environ.get(BUILDER_NAME)
  if not name:
    print 'Use -n $BUILDBOT_NAME for the bot you would like to emulate.'
    sys.exit(1)

  return name, True


def Clobber():
  """
  Clobbers the builder before we do the build, if appropriate.

  - mode: either 'debug' or 'release'
  """
  if os.environ.get(BUILDER_CLOBBER) != "1":
    return

  with BuildStep('Clobber'):
    cmd = [sys.executable,
           './tools/clean_output_directory.py']
    print 'Clobbering %s' % (' '.join(cmd))
    RunProcess(cmd)


def RunTest(name, build_info, targets, flags=None):
  """
  Runs test.py with the given settings.
  """
  if not flags:
    flags = []

  step_name = GetStepName(name, flags)
  with BuildStep(step_name):
    sys.stdout.flush()

    cmd = [
      sys.executable, os.path.join(os.curdir, 'tools', 'test.py'),
      '--step_name=' + step_name,
      '--mode=' + build_info.mode,
      '--compiler=' + build_info.compiler,
      '--runtime=' + build_info.runtime,
      '--arch=' + build_info.arch,
      '--progress=buildbot',
      '-v', '--time', '--use-sdk', '--report'
    ]

    if build_info.checked:
      cmd.append('--checked')

    cmd.extend(flags)
    cmd.extend(targets)

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


def RunProcess(command):
  """
  Runs command.

  If a non-zero exit code is returned, raises an OSError with errno as the exit
  code.
  """
  no_color_env = dict(os.environ)
  no_color_env['TERM'] = 'nocolor'

  exit_code = subprocess.call(command, env=no_color_env)
  if exit_code != 0:
    raise OSError(exit_code)


def GetStepName(name, flags):
  """
  Filters out flags with '=' as this breaks the /stats feature of the buildbot.
  """
  flags = [x for x in flags if not '=' in x]
  return ('%s tests %s' % (name, ' '.join(flags))).strip()
