#!/usr/bin/python
# Copyright (c) 2011, 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.

# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Dart client buildbot steps

Compiles dart client apps with dartc, and run the client tests both in headless
chromium and headless dartium.
"""

import imp
import os
import platform
import re
import socket
import subprocess
import sys

BUILDER_NAME = 'BUILDBOT_BUILDERNAME'
BUILDER_CLOBBER = 'BUILDBOT_CLOBBER'
REVISION = 'BUILDBOT_REVISION'

# latest dartium location
DARTIUM_VERSION_FILE = 'client/tests/drt/LAST_VERSION'
DARTIUM_V_MATCHER = (
    'gs://dartium-archive/[^/]*/dartium-\w*-inc-([0-9]*).([0-9]*).zip')

def GetUtils():
  '''Dynamically load the tools/utils.py python module.'''
  dart_dir = os.path.abspath(os.path.join(__file__, '..', '..', '..'))
  return imp.load_source('utils', os.path.join(dart_dir, 'tools', 'utils.py'))

utils = GetUtils()

def GetBuildInfo():
  """Returns a tuple (name, version, mode) where:
    - name: A name for the build - the buildbot host if a buildbot.
    - version: A version string corresponding to this build.
  """
  name = None
  version = None

  # Populate via builder environment variables.
  name = os.environ.get(BUILDER_NAME)
  version = os.environ.get(REVISION)

  # Fall back if not on builder.
  if not name:
    name = socket.gethostname().split('.')[0]
  if not version:
    # In Windows we need to run in the shell, so that we have all the
    # environment variables available.
    pipe = subprocess.Popen(
        ['svnversion', '-n'], stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        shell=True)
    output = pipe.communicate()
    if pipe.returncode == 0:
      version = output[0]
    else:
      version = 'unknown'
  return (name, version)

def GetOutDir(mode):
  '''
  get the location to place the output

  args:
  utils - the tools/utils.py module
  mode - the mode release or debug
  '''
  return utils.GetBuildRoot(utils.GuessOS(), mode, utils.ARCH_GUESS)

def ProcessTools(mode, name, version):
  '''
  build and test the tools

  args:
  srcpath - the location of the source code to build
  mode - the mode release or debug
  version - the svn version of the currently checked out code
  '''
  print 'ProcessTools'

  toolsBuildScript = os.path.join('.', 'editor', 'build', 'build.py')

  # TODO(devoncarew): should we move this into GetBuildInfo()?
  # get the latest changed revision from the current repository sub-tree
  version = GetLatestChangedRevision()

  outdir = GetOutDir(mode)
  cmds = [sys.executable, toolsBuildScript,
          '--mode=' + mode, '--revision=' + version,
          '--name=' + name, '--out=' + outdir]
  local_env = EnvironmentWithoutBotoConfig()
  #if 'linux' in name:
  #  javahome = os.path.join(os.path.expanduser('~'), 'jdk1.6.0_25')
  #  local_env['JAVA_HOME'] = javahome
  #  local_env['PATH'] = (os.path.join(javahome, 'bin') +
  #                       os.pathsep + local_env['PATH'])

  return subprocess.call(cmds, env=local_env)

def EnvironmentWithoutBotoConfig(environment=None):
  # The buildbot sets AWS_CREDENTIAL_FILE/BOTO_CONFIG to the chromium specific
  # file, we use the one in home.
  custom_env = dict(environment or os.environ)
  if 'BOTO_CONFIG' in custom_env:
    del custom_env['BOTO_CONFIG']
  if 'AWS_CREDENTIAL_FILE' in custom_env:
    del custom_env['AWS_CREDENTIAL_FILE']
  return custom_env

def ProcessBot(name, target, custom_env=None):
  '''
  Build and test the named bot target (compiler, android, pub). We look for
  the supporting script in tools/bots/ to run the tests and build.
  '''
  print 'Process%s' % target.capitalize()
  has_shell = False
  environment = custom_env or os.environ
  if '-win' in name:
    # In Windows we need to run in the shell, so that we have all the
    # environment variables available.
    has_shell = True
  return subprocess.call([sys.executable,
      os.path.join('tools', 'bots', target + '.py')],
      env=environment, shell=has_shell)

def FixJavaHome():
  buildbot_javahome = os.getenv('BUILDBOT_JAVA_HOME')
  if buildbot_javahome:
    current_pwd = os.getenv('PWD')
    if platform.system() != 'Windows':
      java_home = '/usr/lib/jvm/java-6-sun' # Hackety-hack. Please remove!
    else:
      java_home = os.path.join(current_pwd, buildbot_javahome)
    java_bin = os.path.join(java_home, 'bin')
    os.environ['JAVA_HOME'] = java_home
    os.environ['PATH'] = '%s;%s' % (java_bin, os.environ['PATH'])

    print 'Setting java home to ', java_home
    sys.stdout.flush()

def ClobberBuilder():
  """ Clobber the builder before we do the build.
  """
  cmd = [sys.executable,
         './tools/clean_output_directory.py']
  print 'Clobbering %s' % (' '.join(cmd))
  return subprocess.call(cmd)

def GetShouldClobber():
  return os.environ.get(BUILDER_CLOBBER) == "1"

def GetLatestChangedRevision():
  revision = utils.GetSVNRevision()
  if not revision:
    raise Exception("Couldn't determine last changed revision.")
  return revision

def main():
  if len(sys.argv) == 0:
    print 'Script pathname not known, giving up.'
    return 1

  scriptdir = os.path.dirname(sys.argv[0])
  # Get at the top-level directory. This script is in client/tools
  os.chdir(os.path.abspath(os.path.join(scriptdir, os.pardir, os.pardir)))

  if GetShouldClobber():
    print '@@@BUILD_STEP Clobber@@@'
    status = ClobberBuilder()
    if status != 0:
      print '@@@STEP_FAILURE@@@'
      return status


  #TODO(sigmund): remove this indirection once we update our bots
  (name, version) = GetBuildInfo()
  # The buildbot will set a BUILDBOT_JAVA_HOME relative to the dart
  # root directory, set JAVA_HOME based on that.
  FixJavaHome()
  if name.startswith('dart-editor'):
    # TODO(kustermann,ricow): This is a temporary hack until we can safely
    # enable it on main waterfall. We need to remove this eventually
    if name.startswith('dart-editor-fyi'):
      match = re.search('dart-editor-fyi(.*)', name)
      name = 'dart-editor' + match.group(1)
      # In case we're an FYI builder, run 'tools/bots/editor.py'.
      status = ProcessBot(name, 'editor',
                          custom_env=EnvironmentWithoutBotoConfig())
    else:
      # Run the old annotated steps script
      status = ProcessTools('release', name, version)
  elif name.startswith('pub-'):
    status = ProcessBot(name, 'pub')
  elif name.startswith('vm-android'):
    status = ProcessBot(name, 'android')
  elif name.startswith('cross') or name.startswith('target'):
    status = ProcessBot(name, 'cross-vm',
                        custom_env=EnvironmentWithoutBotoConfig())
  else:
    status = ProcessBot(name, 'compiler')

  if status:
    print '@@@STEP_FAILURE@@@'

  return status


if __name__ == '__main__':
  sys.exit(main())
