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

"""Common utilities for all buildbot scripts that specifically don't rely
on having a full chromium checkout.
"""

import os
import subprocess
import sys

from build_paths import SDK_SRC_DIR, NACL_DIR, SRC_DIR

sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
import oshelpers
import getos


verbose = True


def IsSDKBuilder():
  """Returns True if this script is running on an SDK builder.

  False means it is either running on a trybot, or a user's machine.

  Trybot names:
    (win|mac|linux)_nacl_sdk

  Build-only Trybot names:
    (win|mac|linux)_nacl_sdk_build

  Builder names:
    (windows|mac|linux)-sdk-multi(rel)?"""
  bot =  os.getenv('BUILDBOT_BUILDERNAME', '')
  return '-sdk-multi' in bot


def ErrorExit(msg):
  """Write and error to stderr, then exit with 1 signaling failure."""
  sys.stderr.write(str(msg) + '\n')
  sys.exit(1)


def Trace(msg):
  if verbose:
    sys.stderr.write(str(msg) + '\n')


def GetWindowsEnvironment():
  if oshelpers.FindExeInPath('cl.exe') is not None:
    # cl.exe is already in the path, let's just use that.
    return os.environ

  sys.path.append(os.path.join(NACL_DIR, 'buildbot'))
  import buildbot_standard

  # buildbot_standard.SetupWindowsEnvironment expects a "context" object. We'll
  # fake enough of that here to work.
  class FakeContext(object):
    def __init__(self):
      self.env = os.environ

    def GetEnv(self, key):
      return self.env[key]

    def __getitem__(self, key):
      # The nacl side script now needs gyp_vars to return a list.
      if key == 'gyp_vars':
        return []
      return self.env[key]

    def SetEnv(self, key, value):
      self.env[key] = value

    def __setitem__(self, key, value):
      self.env[key] = value

  context = FakeContext()
  buildbot_standard.SetupWindowsEnvironment(context)

  env_script = 'vcvarsall.bat'

  if not oshelpers.FindExeInPath(env_script):
    # This might happen if Visual Studio is not installed. Check to see if
    # vs2013 is in depot_tools.

    # Find depot_tools by looking for gclient.bat.
    gclient_bat = oshelpers.FindExeInPath('gclient.bat')
    if gclient_bat is None:
      ErrorExit('gclient.bat is not in the path. Where is depot_tools?')

    depot_tools_dir = os.path.dirname(gclient_bat)
    vs2013_dir = os.path.join(depot_tools_dir, 'win_toolchain', 'vs2013_files')
    if not os.path.exists(vs2013_dir):
      ErrorExit('Visual Studio not installed normally or in depot_tools.')

    # The depot_tools vs2013 toolchain has its own batch file (not
    # vcvarsall.bat) for setting the environment variables needed by vs2013.
    env_script = os.path.join(vs2013_dir, 'win8sdk', 'bin', 'SetEnv.cmd')

  # Running the env_script adds the correct directories to the path for
  # executables (e.g. cl.exe, link.exe), include paths, lib directories, etc,
  # which we extract below.
  process = subprocess.Popen(env_script + ' x86 > NUL && set',
      stdout=subprocess.PIPE, env=context.env, shell=True)
  stdout, _ = process.communicate()

  # Parse environment from "set" command above.
  # It looks like this:
  # KEY1=VALUE1\r\n
  # KEY2=VALUE2\r\n
  # ...
  return dict(line.split('=', 1) for line in stdout.split('\r\n')[:-1])


def BuildStep(name):
  """Annotate a buildbot build step."""
  sys.stdout.flush()
  sys.stderr.write('\n@@@BUILD_STEP %s@@@\n' % name)


def Run(args, cwd=None, env=None, shell=False):
  """Start a process with the provided arguments.

  Starts a process in the provided directory given the provided arguments. If
  shell is not False, the process is launched via the shell to provide shell
  interpretation of the arguments.  Shell behavior can differ between platforms
  so this should be avoided when not using platform dependent shell scripts."""

  # We need to modify the environment to build host on Windows.
  if not env and getos.GetPlatform() == 'win':
    env = GetWindowsEnvironment()

  Trace('Running: ' + ' '.join(args))
  sys.stdout.flush()
  sys.stderr.flush()
  try:
    subprocess.check_call(args, cwd=cwd, env=env, shell=shell)
  except subprocess.CalledProcessError as e:
    sys.stdout.flush()
    sys.stderr.flush()
    ErrorExit('buildbot_common: %s' % e)

  sys.stdout.flush()
  sys.stderr.flush()


def ShortFilename(filename):
  drive = os.path.splitdrive(filename)[0]
  if drive and drive != os.path.splitdrive(SRC_DIR)[0]:
    return filename
  return os.path.relpath(filename, SRC_DIR)


def CopyDir(src, dst, excludes=('.svn', '*/.svn')):
  """Recursively copy a directory using."""
  args = ['-r', src, dst]
  for exc in excludes:
    args.append('--exclude=' + exc)
  Trace('cp -r %s %s' % (ShortFilename(src), ShortFilename(dst)))
  if os.path.abspath(src) == os.path.abspath(dst):
    ErrorExit('ERROR: Copying directory onto itself: ' + src)
  oshelpers.Copy(args)


def CopyFile(src, dst):
  Trace('cp %s %s' % (ShortFilename(src), ShortFilename(dst)))
  if os.path.abspath(src) == os.path.abspath(dst):
    ErrorExit('ERROR: Copying file onto itself: ' + src)
  args = [src, dst]
  oshelpers.Copy(args)


def RemoveDir(dst):
  """Remove the provided path."""
  Trace('rm -fr ' + ShortFilename(dst))
  oshelpers.Remove(['-fr', dst])


def MakeDir(dst):
  """Create the path including all parent directories as needed."""
  Trace('mkdir -p ' + ShortFilename(dst))
  oshelpers.Mkdir(['-p', dst])


def Move(src, dst):
  """Move the path src to dst."""
  Trace('mv -f %s %s' % (ShortFilename(src), ShortFilename(dst)))
  oshelpers.Move(['-f', src, dst])


def RemoveFile(dst):
  """Remove the provided file."""
  Trace('rm ' + ShortFilename(dst))
  oshelpers.Remove(['-f', dst])


BOT_GSUTIL = '/b/build/scripts/slave/gsutil'
# On Windows, the current working directory may be on a different drive than
# gsutil.
WIN_BOT_GSUTIL = 'E:' + BOT_GSUTIL
LOCAL_GSUTIL = 'gsutil'


def GetGsutil():
  if os.environ.get('BUILDBOT_BUILDERNAME') \
     and not os.environ.get('BUILDBOT_FAKE'):
    if getos.GetPlatform() == 'win':
      return WIN_BOT_GSUTIL
    return BOT_GSUTIL
  else:
    return LOCAL_GSUTIL


def Archive(filename, bucket_path, cwd=None, step_link=True):
  """Upload the given filename to Google Store."""
  full_dst = 'gs://%s/%s' % (bucket_path, filename)

  # Since GetGsutil() might just return 'gsutil' and expect it to be looked
  # up in the PATH, we must pass shell=True on windows.
  # Without shell=True the windows implementation of subprocess.call will not
  # search the PATH for the executable: http://bugs.python.org/issue8557
  shell = getos.GetPlatform() == 'win'

  cmd = [GetGsutil(), 'cp', '-a', 'public-read', filename, full_dst]
  Run(cmd, shell=shell, cwd=cwd)
  url = 'https://storage.googleapis.com/%s/%s' % (bucket_path, filename)
  if step_link:
    sys.stdout.flush()
    sys.stderr.write('@@@STEP_LINK@download@%s@@@\n' % url)
