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

  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%s"
           ) % (self.compiler, self.runtime, self.mode, self.system,
                self.checked, self.host_checked, self.minified, self.test_set,
                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,
            '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()
    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,
      '--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()
