#! -*- python -*-
#
# 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.

""" Main scons script for Native Client SDK builds.

Do not invoke this script directly, but instead use the scons or scons.bat
wrapper function.  E.g.

Linux or Mac:
  ./scons [Options...]

Windows:
  scons.bat [Options...]
"""

from __future__ import with_statement

import os
import platform
import subprocess
import sys
import toolchainbinaries
from build_tools import build_utils

# ----------------------------------------------------------------------------
HELP_STRING = """
===============================================================================
Help for NaCl SDK
===============================================================================

* cleaning:            ./scons -c
* build a target:      ./scons <target>

Supported targets:
  * bot                   Runs everything that the build and try bots run.
  * debug_server_x64      Build the out-of-process debug_server.
  * debug_server_Win32    Build the out-of-process debug_server.
  * docs                  Build all of the Doxygen documentation.
  * examples              Build the examples.
  * installer             Build the SDK installer.
  * nacl-bpad             Build the native client crash reporting tool.
  * sdk_tools             Build nacl_sdk.zip and sdk_tools.tgz
  * toolchain             Update the toolchain's headers and libraries.
  * vsx                   Build the Visual Studio Plugin.

Flags:
  * USE_EXISTING_INSTALLER=1        Do not rebuild the installer if it exists.
  * chrome_browser_path=<full_path> Download Chrome to <full_path>.
  * SHOW_BROWSER=1                  Don't suppress browser GUI while performing
                                    browser tests in Linux.

More targets are listed below in the automatically generated help section.

===============================================================================
Automatically generated help follows:
===============================================================================
"""

# ----------------------------------------------------------------------------
# Perform some environment checks before running.
# Note that scons should set NACL_SDK_ROOT before this script runs.

if os.getenv('NACL_SDK_ROOT') is None:
  sys.stderr.write('NACL_SDK_ROOT must be defined as the root directory'
                   ' of NaCl SDK.\n')
  sys.exit(1)

# By default, run with a parallel build (i.e. '-j num_jobs').
# Use a default value proportional to the number of cpu cores on the system.
# To run a serial build, explicitly type '-j 1' on the command line.
try:
  import multiprocessing
  CORE_COUNT = multiprocessing.cpu_count()
except (ImportError, NotImplementedError):
  CORE_COUNT = 2  # Our buildbots seem to be dual-core typically

SetOption('num_jobs', CORE_COUNT * 2)
print 'Building with', GetOption('num_jobs'), 'parallel jobs'

# ----------------------------------------------------------------------------
# The environment_list contains all the build environments that we want to
# specify.  Selecting a particular environment is done using the --mode option.
# Each environment that we support gets appended to this list.
environment_list = []

# ----------------------------------------------------------------------------
# Create the base environment, from which all other environments are derived.
base_env = Environment(
    tools = ['component_setup'],
    CPPPATH = ['$MAIN_DIR'],
    CPPDEFINES = [
      'BOOST_ALL_NO_LIB',
    ],
    NACL_TOOLCHAIN_ROOTS = {
        ('x86', 'newlib'):
          build_utils.NormalizeToolchain(arch='x86', variant='newlib'),
        ('x86', 'glibc'):
          build_utils.NormalizeToolchain(arch='x86', variant='glibc'),
    },
    ROOT_DIR = os.path.abspath(os.getcwd()),
    SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd()))),
    IS_WINDOWS = sys.platform in ['cygwin', 'win32'],
    IS_LINUX = sys.platform == 'linux2',
    IS_MAC = sys.platform == 'darwin',
    JOB_COUNT = GetOption('num_jobs')
)

# It is possible to override these values on the command line by typing
# something like this:
#   PYTHON=/path/to/my/python
base_env.SetDefault(
    PYTHON = ARGUMENTS.get('PYTHON', 'python'),
    USE_EXISTING_INSTALLER = ARGUMENTS.get('USE_EXISTING_INSTALLER', False),
    SHOW_BROWSER = ARGUMENTS.get('SHOW_BROWSER', False),
)

base_env.Append(
    BUILD_SCONSCRIPTS = [
        # Keep in alphabetical order
        'build_tools/build.scons',
        'documentation/build.scons',
        'project_templates/test.scons',
    ],
)

base_env.Help(HELP_STRING)

KNOWN_SUITES = frozenset([
    'bot',
    ])


def HasBotTarget(env):
  if 'bot' in COMMAND_LINE_TARGETS:
    return True
  return False

base_env.AddMethod(HasBotTarget)


def CheckSuiteName(suite, node_name):
  '''Check whether a given test suite or alias name is a known name.

  If the suite name is not in the approved list, then this function throws
  an exception, with the node_name within the error message.

  Args:
    suite: a name of a suite that must be in the KNOWN_SUITES set
    node_name: The name of the node.  This is used for error messages
  '''
  if suite not in KNOWN_SUITES:
    raise Exception('Testsuite/Alias "%s" for target "%s" is unknown' %
                    (suite, node_name))


def AddNodeToTestSuite(env, node, suite_names, node_name, test_size='all'):
  '''Adds a test node to a given set of suite names

  These tests are automatically added to the run_all_tests target and are
  listed in the help screen.

  This function is loosely based on a function of the same name in the
  Native Client repository

  Args:
    env - The environment from which this function was called
    node - A scons node (e.g., file, command, etc) to be added to set suite
    suite_names - A list of test suite names.  For none, pass an empty list
    node_name - The target name used for running this test
    test_size - The relative run-time of this test: small, medium, or large
  '''

  # CommandTest can return an empty list when it silently discards a test
  if not node:
    return

  AlwaysBuild(node)

  for s in suite_names:
    CheckSuiteName(s, node_name)
    env.Alias(s, node)

  if test_size not in ['small', 'medium', 'large', 'all']:
    raise Exception('Invalid test size for %s' % node_name)

  # Note that COMPONENT_TEST_SIZE is set to 'large' by default, which
  # populates a largely redundant list of 'large' tests.  Note that all
  # tests are added to 'all', so setting test_size='all' is a no-op
  env.ComponentTestOutput(node_name, node, COMPONENT_TEST_SIZE=test_size)

base_env.AddMethod(AddNodeToTestSuite)


def ShouldBeCleaned(env, targets, suite_names, node_name):
  '''Determines whether a given set of targets require cleaning.

  Args:
    env - The calling environment.
    targets - Any build artifacts to which a cleaning step might apply.
              Any false object indicates that this check is skipped.
    suite_names - Any suites that might produce |targets|
    node_name - A node that might produce |targets|
  '''
  if not env.GetOption('clean'):
    return False

  if len(COMMAND_LINE_TARGETS) > 0:
    clean_this = False
    for cl_target in COMMAND_LINE_TARGETS:
      if cl_target in suite_names or cl_target == node_name:
        clean_this = True
        break
    if not clean_this:
      return False

  if not targets:
    return True
  for target in targets:
    if os.path.exists(target):
      return True
  return False


def AddCleanAction(env, targets, action, suite_names, node_name):
  '''Adds a cleanup action that scons cannot detect automatically.

  Cleaning will only occur if there is a match between the suite or nodes
  specified on the command line, and suite_names or node_name or if no
  suite or nodes are specified on the command line.  Also, at least one of the
  targets must exist on the file system.

  Args:
    env - The calling environment
    targets - Artifacts to be cleaned.
    action - The action to be performed.  It is up to the caller to ensure
             that |action| will actually remove |targets|
    suite_names - Any suites to which this cleanup target applies.
    node_name - Any nodes to which this cleanup target applies.
  '''
  if ShouldBeCleaned(env, targets, suite_names, node_name):
    env.Execute(action)

base_env.AddMethod(AddCleanAction)


def AddNodeAliases(env, node, suite_names, node_name):
  '''Allow a given node to be built under a different name or as a suite

  Args:
    env - The calling environment
    node - A target node to add to a known build alias (e.g., 'bot')
    suite_names - A list of suite names.  For none, pass an empty list.  This
                  node will be run whenever any of these suites are invoked.
                  Each suite name must match a string in KNOWN_SUITES.
    node_name - The name of this node, when run by itself
  '''

  if not node:
    return

  for s in suite_names:
    CheckSuiteName(s, node_name)
    env.Alias(s, node)

  env.Alias(node_name, node)

base_env.AddMethod(AddNodeAliases)


def CreatePythonUnitTest(env, filename, dependencies=None, disabled=False,
                         params=None, buffered=True, banner=None):
  """Returns a new build command that will run a unit test with a given file.

  Args:
    env: SCons environment
    filename: The python file that contains the unit test
    dependencies: An optional list of other files that this unit test uses
    disabled: Setting this to True will prevent the test from running
    params: Optional additional parameters for python command
    buffered: True=stdout is buffered until entirely complete;
              False=stdout is immediately displayed as it occurs.
    banner: (optional) annotation banner for build/try bots

  Returns:
    A SCons command node
  """
  dependencies = dependencies or []
  params = params or []

  basename = os.path.splitext(os.path.basename(filename))[0]
  outfilename = "%s_output.txt" % basename


  def RunPythonUnitTest(env, target, source):
    """Runs unit tests using the given target as a command.

    The argument names of this test are not very intuitive but match what is
    used conventionally throughout scons.  If the string "PASSED" does not
    occur in target when this exits, the test has failed; also a scons
    convention.

    Args:
      env: SCons's current environment.
      target: Where to write the result of the test.
      source: The command to run as the test.

    Returns:
      None for good status
      An error string for bad status
    """
    bot = build_utils.BotAnnotator()
    if banner:
      bot.BuildStep(banner)

    if disabled:
      sys.stdout.write("Test %s is disabled.\n" % basename)
      sys.stdout.flush()
      return None   # return with good status

    import subprocess

    app = [str(env['PYTHON']), str(source[0].abspath)] + map(
        lambda param: param if type(param) is str else str(param.abspath),
        params)
    bot.Print('Running: %s' % app)
    app_env = os.environ.copy()
    # We have to do this because scons overrides PYTHONPATH and does
    # not preserve what is provided by the OS.
    python_path = [env['ROOT_DIR'], app_env['PYMOX'], app_env['PYTHONPATH']]
    app_env['PYTHONPATH'] = os.pathsep.join(python_path)
    ret_val = 'Error: General Test Failure'  # Indicates failure, by default
    target_str = str(target[0])
    with open(target_str, 'w') as outfile:
      def Write(str):
        if buffered:
          outfile.write(str)
          outfile.flush()
        else:
          sys.stdout.write(str)
          sys.stdout.flush()
      Write('\n-----Begin output for Test: %s\n' % basename)
      if subprocess.call(app, env=app_env,
                         stdout=outfile if buffered else None,
                         stderr=outfile if buffered else None):
        Write('-----Error: unit test failed\n')
        ret_val = 'Error: Test Failure in %s' % basename
      else:
        ret_val = None  # Indicates success

      Write('-----End output for Test: %s\n' % basename)
    if buffered:
      with open(target_str, 'r') as resultfile:
        sys.stdout.write(resultfile.read())
      sys.stdout.flush()

    if ret_val:
      bot.BuildStepFailure()

    return ret_val

  cmd = env.Command(outfilename, filename, RunPythonUnitTest)
  env.Depends(cmd, dependencies)
  # Create dependencies for all the env.File parameters and other scons nodes
  for param in params:
    if type(param) is not str:
      env.Depends(cmd, param)

  return cmd

base_env.AddMethod(CreatePythonUnitTest)


# ----------------------------------------------------------------------------
# Support for running Chrome.  These functions access the construction
# Environment() to produce a path to Chrome.

# A Dir object representing the directory where the Chrome binaries are kept.
# You can use chrome_binaries_dir= to set this on the command line.  Defaults
# to chrome_binaries.
base_env['CHROME_DOWNLOAD_DIR'] = \
    base_env.Dir(ARGUMENTS.get('chrome_binaries_dir', '#chrome_binaries'))


def ChromeArchitectureSpec(env):
  '''Determine the architecture spec for the Chrome binary.

  The architecture spec is a string that represents the host architecture.
  Possible values are:
    x86-32
    x86-64
  On Mac and Windows, the architecture spec is always x86-32, because there are
  no 64-bit version available.

  Returns: An architecture spec string for the host CPU.
  '''
  arch, _ = platform.architecture();
  # On Mac and Windows, always use a 32-bit version of Chrome (64-bit versions
  # are not available).
  if env['IS_WINDOWS'] or env['IS_MAC']:
    arch = 'x86-32'
  else:
    arch = 'x86-64' if '64' in arch else 'x86-32'
  return arch

base_env.AddMethod(ChromeArchitectureSpec)


def GetDefaultChromeBinary(env):
  '''Get a File object that represents a Chrome binary.

  By default, the test infrastructure will download a copy of Chrome that can
  be used for testing.  This method returns a File object that represents the
  downloaded Chrome binary that can be run by tests.  Note that the path to the
  binary is specific to the host platform, for example the path on Linux
  is <chrome_dir>/linux/<arch>/chrome, while on Mac it's
    <chrome_dir>/mac/<arch>/Chromium.app/Contents.MacOS/Chromium.

  Returns: A File object representing the Chrome binary.
  '''
  if env['IS_LINUX']:
    os_name = 'linux'
    binary = 'chrome'
  elif env['IS_WINDOWS']:
    os_name = 'windows'
    binary = 'chrome.exe'
  elif env['IS_MAC']:
    os_name = 'mac'
    binary = 'Chromium.app/Contents/MacOS/Chromium'
  else:
    raise Exception('Unsupported OS')

  return env.File(os.path.join(
      '${CHROME_DOWNLOAD_DIR}',
      '%s_%s' % (os_name, env.ChromeArchitectureSpec()),
      binary)) 

base_env.AddMethod(GetDefaultChromeBinary)


def GetChromeBinary(env):
  '''Return a File object that represents the downloaded Chrome binary.

  If chrome_browser_path is specified on the command line, then return a File
  object that represents that path.  Otherwise, return a File object
  representing the default downloaded Chrome (see GetDefaultChromeBinary(),
  above).

  Returns: A File object representing a Chrome binary.
  '''
  return env.File(ARGUMENTS.get('chrome_browser_path',
                                env.GetDefaultChromeBinary()))

base_env.AddMethod(GetChromeBinary)


def DependsOnChrome(env, dependency):
  '''Create a dependency on the download of Chrome.

  Creates a dependency in |env| such that Chrome gets downloaded (if necessary)
  whenever |dependency| changes.  Uses the Chrome downloader scripts built
  into NaCl; this script expects NaCl to be DEPS'ed into
  third_party/native_client/native_client.

  The Chrome binary is added as a precious node to the base Environment.  If
  we added it to the build environment env, then downloading chrome would in
  effect be specified for multiple environments.
  '''
  if not hasattr(base_env, 'download_chrome_node'):
    chrome_binary = env.GetDefaultChromeBinary()
    download_chrome_script = build_utils.JoinPathToNaClRepo(
        'native_client', 'build', 'download_chrome.py',
        root_dir=env['ROOT_DIR'])
    base_env.download_chrome_node = env.Command(
        chrome_binary,
        [],
        '${PYTHON} %s --arch=%s --dst=${CHROME_DOWNLOAD_DIR}' %
            (download_chrome_script, env.ChromeArchitectureSpec()))
    # This stops Scons from deleting the file before running the step above.
    env.NoClean(chrome_binary)
    env.Precious(chrome_binary)
  env.Depends(dependency, base_env.download_chrome_node)

base_env.AddMethod(DependsOnChrome)


# ----------------------------------------------------------------------------
# Targets for updating sdk headers and libraries
# NACL_SDK_XXX vars are defined by  site_scons/site_tools/naclsdk.py
# NOTE: Our task here is complicated by the fact that there might already be
#       some (outdated) headers/libraries at the new location
#       One of the hacks we employ here is to make every library depend
#       on the installation on ALL headers (sdk_headers)

# Contains all the headers to be installed
sdk_headers = base_env.Alias('extra_sdk_update_header', [])
# Contains all the libraries and .o files to be installed
libs_platform = base_env.Alias('extra_sdk_libs_platform', [])
libs = base_env.Alias('extra_sdk_libs', [])
base_env.Alias('extra_sdk_update', [libs, libs_platform])

AlwaysBuild(sdk_headers)

# ----------------------------------------------------------------------------
# The following section contains proxy nodes which can be used to create
# dependencies between targets that are not in the same scope or environment.
toolchain_node = base_env.Alias('toolchain', [])


def GetToolchainNode(env):
  '''Returns the node associated with the toolchain build target'''
  return toolchain_node

base_env.AddMethod(GetToolchainNode)


def GetHeadersNode(env):
  return sdk_headers

base_env.AddMethod(GetHeadersNode)

installer_prereqs_node = base_env.Alias('installer_prereqs', [])


def GetInstallerPrereqsNode(env):
  return installer_prereqs_node

base_env.AddMethod(GetInstallerPrereqsNode)

installer_test_node = base_env.Alias('installer_test_node', [])


def GetInstallerTestNode(env):
  return installer_test_node

base_env.AddMethod(GetInstallerTestNode)


def AddHeaderToSdk(env, nodes, subdir = 'nacl/', base_dirs = None):
  """Add a header file to the toolchain.  By default, Native Client-specific
  headers go under nacl/, but there are non-specific headers, such as
  the OpenGLES2 headers, that go under their own subdir.

  Args:
    env: Environment in which we were called.
    nodes: A list of node objects to add to the toolchain
    subdir: This is appended to each base_dir
    base_dirs: A list of directories to install the node to"""
  if not base_dirs:
    # TODO(mball): This won't work for PNaCl:
    base_dirs = [os.path.join(dir, 'x86_64-nacl', 'include')
                 for dir in env['NACL_TOOLCHAIN_ROOTS'].values()]

  for base_dir in base_dirs:
    node = env.Replicate(os.path.join(base_dir, subdir), nodes)
    env.Depends(sdk_headers, node)
    env.Depends(toolchain_node, node)
  return node

base_env.AddMethod(AddHeaderToSdk)


def AddLibraryToSdkHelper(env, nodes, is_lib, is_platform):
  """"Helper function to install libs/objs into the toolchain
  and associate the action with the extra_sdk_update.

  Args:
    env: Environment in which we were called.
    nodes: list of libc/objs
    is_lib: treat nodes as libs
    is_platform: nodes are truly platform specific
  """
  env.Requires(nodes, sdk_headers)

  dir = ARGUMENTS.get('extra_sdk_lib_destination')
  if not dir:
    dir = '${NACL_SDK_LIB}/'

  if is_lib:
    n = env.ReplicatePublished(dir, nodes, 'link')
  else:
    n = env.Replicate(dir, nodes)

  if is_platform:
    env.Alias('extra_sdk_libs_platform', n)
  else:
    env.Alias('extra_sdk_libs', n)
  return n


def AddLibraryToSdk(env, nodes, is_platform=False):
  return AddLibraryToSdkHelper(env, nodes, True, is_platform)

base_env.AddMethod(AddLibraryToSdk)


# ----------------------------------------------------------------------------
# This is a simple environment that is primarily for targets that aren't built
# directly by scons, and therefore don't need any special environment setup.
build_env = base_env.Clone(
    BUILD_TYPE = 'build',
    BUILD_GROUPS = ['default', 'all'],
    BUILD_TYPE_DESCRIPTION = 'Default build environment',
    HOST_PLATFORMS = '*',
    )

environment_list.append(build_env)

# ----------------------------------------------------------------------------
# Get the appropriate build command depending on the environment.


def SconsBuildCommand(env):
  '''Return the build command used to run separate scons instances.
  Args:
    env: The construction Environment() that is building using scons.
  Returns:
    A string representing the platform-specific build command that will run the
    scons instances.
  '''
  if env['IS_WINDOWS']:
    return 'scons.bat --jobs=%s' % GetOption('num_jobs')
  else:
    return './scons --jobs=%s' % GetOption('num_jobs')

# ----------------------------------------------------------------------------
# Add a builder for examples.  This adds an Alias() node named 'examples' that
# is always built.  There is some special handling for the clean mode, since
# SCons relies on actual build products for its clean processing and will not
# run Alias() actions during clean unless they actually produce something.


def BuildExamples(env, target, source):
  '''Build the examples.

  This runs the build command in the 'examples' directory.

  Args:
    env: The construction Environment() that is building the examples.
    target: The target that triggered this build.  Not used.
    source: The sources used for this build.  Not used.
  '''
  os_env = os.environ.copy()
  os_env['NACL_TARGET_PLATFORM'] = '.'
  subprocess.check_call(SconsBuildCommand(env),
                        cwd='examples',
                        env=os_env,
                        shell=True)


def CleanExamples(env, target, source):
  '''Clean the examples.

  This runs the clean command in the 'examples' directory.

  Args:
    env: The construction Environment() that is building the examples.
  '''
  os_env = os.environ.copy()
  os_env['NACL_TARGET_PLATFORM'] = '.'
  subprocess.check_call('%s --clean' % SconsBuildCommand(env),
                        cwd='examples',
                        env=os_env,
                        shell=True)


examples_builder = build_env.Alias('examples', [toolchain_node], BuildExamples)
build_env.AlwaysBuild(examples_builder)
build_env.AddCleanAction(['examples'], CleanExamples, ['bot'],
                         examples_builder)


def DependsOnExamples(env, dependency):
  env.Depends(dependency, examples_builder)

build_env.AddMethod(DependsOnExamples)


# ----------------------------------------------------------------------------
# Add helper functions that build/clean a test by invoking scons under the
# test directory (|cwd|, when specified).  These functions are meant to be
# called from corresponding project-specific 'Build<project>Test' and
# 'Clean<project>Test' functions in the local test.scons scripts.  Note that the
# CleanNaClTest does not require a |cwd| because its cwd is always '.'


def BuildNaClTest(env, cwd):
  '''Build the test.

  This runs the build command in the test directory from which it is called.

  Args:
    env: The construction Environment() that is building the test.
    cwd: The directory under which the test's build.scons rests.
  '''
  subprocess.check_call('%s stage' % SconsBuildCommand(env),
                        cwd=cwd,
                        shell=True)

build_env.AddMethod(BuildNaClTest)


def CleanNaClTest(env):
  '''Clean the test.

  This runs the clean command in the test directory from which it is called.

  Args:
    env: The construction Environment() that is building the test.
    cwd: The directory under which the test's build.scons rests.
  '''
  subprocess.check_call('%s stage --clean' % SconsBuildCommand(env),
                        shell=True)
  # The step above still leaves behind two empty 'opt' directories, so a second
  # cleaning pass is necessary.
  subprocess.check_call('%s --clean' % SconsBuildCommand(env),
                        shell=True)

build_env.AddMethod(CleanNaClTest)

# ----------------------------------------------------------------------------
# Enable PPAPIBrowserTester() functionality using nacltest.js
# NOTE: The three main functions in this section: PPAPIBrowserTester(),
# CommandTest(), and AutoDepsCommand() are 'LITE' versions of their counterparts
# provided by Native Client @ third_party/native_client/native_client/SConstruct


def SetupBrowserEnv(env):
  '''Set up the environment for running the browser.

  This copies environment parameters provided by the OS in order to run the
  browser reliably.

  Args:
    env: The construction Environment() that runs the browser.
  '''
  EXTRA_ENV = ['XAUTHORITY', 'HOME', 'DISPLAY', 'SSH_TTY', 'KRB5CCNAME']
  for var_name in EXTRA_ENV:
    if var_name in os.environ:
      env['ENV'][var_name] = os.environ[var_name]

  env.Append(
    PYTHONPATH = [
        build_utils.JoinPathToNaClRepo(
            'third_party', 'pylib',
            root_dir=os.getenv('NACL_SDK_ROOT')),
        build_utils.JoinPathToNaClRepo(
            'tools', 'valgrind',
            root_dir=os.getenv('NACL_SDK_ROOT')),
        ]
    )


def PPAPIBrowserTester(env,
                       target,
                       url,
                       files,
                       timeout=20):
  '''The main test wrapper for browser integration tests.

  This constructs the command that invokes the browser_tester.py script on an
  existing Chrome binary (to be downloaded if necessary).

  Args:
    env: The construction Environment() that runs the browser.
    target: The output file to which the output of the test is to be written.
    url: The test web page.
    files: The files necessary for the web page to be served.
    timeout: How long to wait for a response before concluding failure.

  Returns: A command node that executes the browser test.
  '''

  env = env.Clone()
  SetupBrowserEnv(env)

  python_tester_script = build_utils.JoinPathToNaClRepo(
      'native_client', 'tools', 'browser_tester', 'browser_tester.py',
      root_dir=env['ROOT_DIR'])

  # Check if browser GUI needs to be suppressed (possible only in Linux)
  headless_prefix = []
  if not env['SHOW_BROWSER'] and env['IS_LINUX']:
    headless_prefix = ['xvfb-run', '--auto-servernum']

  command = headless_prefix + [
      '${PYTHON}', python_tester_script,
      '--browser_path', env.GetChromeBinary(),
      '--url', url,
      # Fail if there is no response for X seconds.
      '--timeout', str(timeout)]

  for dep_file in files:
    command.extend(['--file', dep_file])

  cmd = env.CommandTest(target,
                         command,
                         # Set to 'huge' so that the browser tester's timeout
                         # takes precedence over the default of the test suite.
                         size='huge',
                         capture_output=False)
  env.DependsOnChrome(cmd)

  return cmd

build_env.AddMethod(PPAPIBrowserTester)


def CommandTest(env,
                name,
                command,
                size='small',
                capture_output=True):
  '''The wrapper for testing execution of a command and logging details.

  This constructs the command that invokes the command_tester.py script on a
  given command.

  Args:
    env: The construction Environment() that runs the command.
    name: The output file to which the output of the tester is to be written.
    command: The command to be tested.
    size: This dictates certain timeout thresholds.
    capture_output: This specifies whether the command's output needs to be
                    captured for further processing. When this option is False,
                    stdout and stderr will be streamed out. For more info, see
                    <NACL_REPO>/native_client/tools/command_tester.py

  Returns: A command node that executes the command test.
  '''
  TEST_TIME_THRESHOLD = {
    'small':   2,
    'medium': 10,
    'large':  60,
    'huge': 1800,
    }

  if not name.endswith('out') or name.startswith('$'):
    raise Exception('ERROR: bad test filename for test output %r' % name)

  arch_string = env.ChromeArchitectureSpec();
  if env['IS_LINUX']:
    platform_string = 'linux'
  elif env['IS_MAC']:
    platform_string = 'mac'
  elif env['IS_WINDOWS']:
    platform_string = 'windows'

  name = '${TARGET_ROOT}/test_results/' + name
  max_time = TEST_TIME_THRESHOLD[size]

  script_flags = ['--name', name,
                  '--report', name,
                  '--time_warning', str(max_time),
                  '--time_error', str(10 * max_time),
                  '--perf_env_description', platform_string + '_' + arch_string,
                  '--arch', 'x86',
                  '--subarch', arch_string[-2:],
                  ]
  if not capture_output:
    script_flags.extend(['--capture_output', '0'])

  test_script = build_utils.JoinPathToNaClRepo(
      'native_client', 'tools', 'command_tester.py',
      root_dir=env['ROOT_DIR'])
  command = ['${PYTHON}', test_script] + script_flags + command
  return AutoDepsCommand(env, name, command)

build_env.AddMethod(CommandTest)


def AutoDepsCommand(env, name, command):
  """AutoDepsCommand() takes a command as an array of arguments.  Each
  argument may either be:

   * a string, or
   * a Scons file object, e.g. one created with env.File() or as the
     result of another build target.

  In the second case, the file is automatically declared as a
  dependency of this command.

  Args:
    env: The construction Environment() that runs the command.
    name: The target file to which the output is to be written.
    command: The command to be executed.

  Returns: A command node in the standard SCons format.
  """
  deps = []
  for index, arg in enumerate(command):
    if not isinstance(arg, str):
      if len(Flatten(arg)) != 1:
        # Do not allow this, because it would cause "deps" to get out
        # of sync with the indexes in "command".
        # See http://code.google.com/p/nativeclient/issues/detail?id=1086
        raise AssertionError('Argument to AutoDepsCommand() actually contains '
                             'multiple (or zero) arguments: %r' % arg)
      command[index] = '${SOURCES[%d].abspath}' % len(deps)
      deps.append(arg)

  return env.Command(name, deps, ' '.join(command))

build_env.AddMethod(AutoDepsCommand)


def BuildVSSolution(env, target_name, solution, project_config=None):
  """BuildVSSolution() Builds a Visual Studio solution.

  Args:
    env: The construction Environment() that runs the command.
    target_name: The name of the target.  Build output will be written to
      [target_name]_build_output.txt.
    solution: The solution to build.
    project_config: A valid project configuration string to pass into devenv.
      This provides support for building specific configurations, i.e.
      'Debug|Win32', 'Debug|x64', 'Release|Win32', 'Release|x64'.  Note that the
      string must be in quotes to work.  devenv will default to Win32 if this
      is not provided.

  Returns the Command() used to build the target, so other targets can be made
  to depend on it.
  """
  vs_build_action = ['vcvarsall', '&&', 'devenv', '${SOURCE}', '/build']
  if project_config:
    vs_build_action.extend([project_config])

  build_command = env.Command(target='%s_build_output.txt' % target_name,
                              source=solution,
                              action=' '.join(vs_build_action))
  env.AddNodeAliases(build_command, ['bot'], target_name)
  return build_command

build_env.AddMethod(BuildVSSolution)


def CleanVSSolution(env, target_name, solution_dir):
  """CleanVSSolution() Cleans up a Visual Studio solution's build results.
  
  The clean target created by this function is added to the 'bot' target as
  well as the target specified.  The function will clean any build artifacts
  that could possibly be generated under the solution directory.

  Args:
    env: The construction Environment() that runs the command.
    target_name: The name of the target which builds whatever should be cleaned
      up.
    solution_dir: The directory under which VS build artifacts are to be
      expected.  This function will look for Debug, Release, and x64 build
      targets.
  """
  clean_targets = [os.path.join(solution_dir, 'Debug'),
                   os.path.join(solution_dir, 'Release'),
                   os.path.join(solution_dir, 'x64')]

  for target in clean_targets:
    clean_action = ['rmdir', '/Q', '/S', target]
    env.AddCleanAction([target],
                       Action(' '.join(clean_action)),
                       ['bot'],
                       target_name)

build_env.AddMethod(CleanVSSolution)


def TestVSSolution(env, target_name, test_container, type, size, build_cmd):
  """Defines a set of tests to be added to the scons test set.

  This function adds a test solution generated by Visual Studio.  It can either
  run mstest or, for natively compiled solutions, it can run an executable.

  Args:
    env: The construction Environment() that runs the command.
    target_name: The name of the target which resulted in the test container.
      A name that clearly marks the target as a test is recommended here.
    test_container: The fully qualified path to the dll or exe that contains
      the tests.
    type: The type test package to expect as a string.  This can be 'dll' or
      'exe'.
    size: Which test harness to add the tests to; small, medium, or large
    build_cmd: The command which builds the target being tested.
  """
  test_action = test_container
  if type is 'dll':
    test_action = ' '.join(['vcvarsall',
                            '&&',
                            'mstest',
                            '/testcontainer:%s' % test_container,
                            '/resultsfile:${TARGET}'])

  # Can't use the test container as SOURCE because it is generated indirectly
  # and using it as source would declare an explicit dependency on a target,
  # generated by scons.  Files that exist in the environment can be used in that
  # way, but only if they exist at the time when scons starts to run, or if
  # the are explicit Command targets.  As a result, source is empty.
  test_command = env.Command(
      target='%s_test_results.trx' % target_name,
      source='',
      action=test_action)

  env.Depends(test_command, build_cmd)
  env.AddNodeToTestSuite(test_command,
                         ['bot'],
                         target_name,
                         size)
  return test_command

build_env.AddMethod(TestVSSolution)


# ----------------------------------------------------------------------------
BuildComponents(environment_list)

# Require specifying an explicit target only when not cleaning
if not GetOption('clean'):
  Default(None)
