#!/usr/bin/python
# Copyright (c) 2012 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Enable 'with' statements in Python 2.5
from __future__ import with_statement

import os.path
import platform
import re
import shutil
import subprocess
import sys
import time

from buildbot_lib import (
    BuildContext, BuildStatus, Command, EnsureDirectoryExists, GNArch,
    ParseStandardCommandLine, RemoveDirectory, RemovePath,
    RemoveGypBuildDirectories, RemoveSconsBuildDirectories, RunBuild, SCons,
    SetupLinuxEnvironment, SetupWindowsEnvironment,
    Step, StepLink, StepText, TryToCleanContents,
    RunningOnBuildbot)


def SetupContextVars(context):
  # The branch is set to native_client on the main bots, on the trybots it's
  # set to ''.  Otherwise, we should assume a particular branch is being used.
  context['branch'] = os.environ.get('BUILDBOT_BRANCH', 'native_client')
  context['off_trunk'] = context['branch'] not in ['native_client', '']


def ValidatorTest(context, architecture, validator, warn_only=False):
  cmd = [
      sys.executable,
      'tests/abi_corpus/validator_regression_test.py',
      '--keep-going',
      '--validator', validator,
      '--arch', architecture
  ]
  if warn_only:
    cmd.append('--warn-only')
  Command(context, cmd=cmd)


def SummarizeCoverage(context):
  Command(context, [
      sys.executable,
      'tools/coverage_summary.py',
      context['platform'] + '-' + context['default_scons_platform'],
  ])


def ArchiveCoverage(context):
  gsutil = '/b/build/third_party/gsutil/gsutil'
  gsd_url = 'http://gsdview.appspot.com/nativeclient-coverage2/revs'
  variant_name = ('coverage-' + context['platform'] + '-' +
                  context['default_scons_platform'])
  coverage_path = variant_name + '/html/index.html'
  revision = os.environ.get('BUILDBOT_REVISION', 'None')
  link_url = gsd_url + '/' + revision + '/' + coverage_path
  gsd_base = 'gs://nativeclient-coverage2/revs'
  gs_path = gsd_base + '/' + revision + '/' + variant_name
  cov_dir = 'scons-out/' + variant_name + '/coverage'
  # Copy lcov file.
  Command(context, [
      sys.executable, gsutil,
      'cp', '-a', 'public-read',
      cov_dir + '/coverage.lcov',
      gs_path + '/coverage.lcov',
  ])
  # Copy html.
  Command(context, [
      sys.executable, gsutil,
      'cp', '-R', '-a', 'public-read',
      'html', gs_path,
  ], cwd=cov_dir)
  print '@@@STEP_LINK@view@%s@@@' % link_url


def DoGNBuild(status, context, force_clang=False, force_arch=None):
  if context['no_gn']:
    return False

  use_clang = force_clang or context['clang']

  # Linux builds (or cross-builds) for every target.  Mac builds for
  # x86-32 and x86-64, and can build untrusted code for others.
  if context.Windows() and context['arch'] != '64':
    # The GN scripts for MSVC barf for a target_cpu other than x86 or x64
    # even if we only try to build the untrusted code.  Windows does build
    # for both x86-32 and x86-64 targets, but the GN Windows MSVC toolchain
    # scripts only support x86-64 hosts--and the Windows build of Clang
    # only has x86-64 binaries--while NaCl's x86-32 testing bots have to be
    # actual x86-32 hosts.
    return False

  if force_arch is not None:
    arch = force_arch
  else:
    arch = context['arch']

  if context.Linux():
    # The Linux build uses a sysroot.  'gclient runhooks' installs this
    # for the default architecture, but this might be a cross-build that
    # gclient didn't know was going to be done.  The script completes
    # quickly when it's redundant with a previous run.
    with Step('update_sysroot', status):
      sysroot_arch = {'arm': 'arm',
                      '32': 'i386',
                      '64': 'amd64',
                      'mips32': 'mips'}[arch]
      Command(context, cmd=[sys.executable,
                            '../build/linux/sysroot_scripts/install-sysroot.py',
                            '--arch=' + sysroot_arch])

  out_suffix = '_' + arch
  if force_clang:
    out_suffix += '_clang'
  gn_out = '../out' + out_suffix

  def BoolFlag(cond):
    return 'true' if cond else 'false'

  gn_newlib = BoolFlag(not context['use_glibc'])
  gn_glibc = BoolFlag(context['use_glibc'])
  gn_arch_name = GNArch(arch)

  gn_gen_args = [
      # The Chromium GN definitions might default enable_nacl to false
      # in some circumstances, but various BUILD.gn files involved in
      # the standalone NaCl build assume enable_nacl==true.
      'enable_nacl=true',
      'target_cpu="%s"' % gn_arch_name,
      'is_debug=' + context['gn_is_debug'],
      'use_gcc_glibc=' + gn_glibc,
      'use_clang_newlib=' + gn_newlib,
  ]

  # is_clang is the GN default for Mac and Linux, so
  # don't override that on "non-clang" bots, but do set
  # it explicitly for an explicitly "clang" bot.
  if use_clang:
    gn_gen_args.append('is_clang=true')

  # The ASan runtime requires libstdc++, and the version on the bots is older
  # than the version in the sysroot, so ASan-built sel_ldr from the sysroot
  # won't run. For now we disable the sysroot (this matches the SCons build)
  # but the term fix would be to just use GN's libcxx build.
  if context['asan']:
    gn_gen_args.append('use_sysroot=false')

  # If this is a 32-bit build but the kernel reports as 64-bit,
  # then gn will set host_cpu=x64 when we want host_cpu=x86.
  if context.Linux() and arch == '32':
    gn_gen_args.append('host_cpu="x86"')

  # Mac can build the untrusted code for machines Mac doesn't
  # support, but the GN files will get confused in a couple of ways.
  if context.Mac() and arch not in ('32', '64'):
    gn_gen_args += [
        # Subtle GN issues mean that $host_toolchain context will
        # wind up seeing current_cpu=="arm" when target_os is left
        # to default to "mac", because host_toolchain matches
        # _default_toolchain and toolchain_args() does not apply to
        # the default toolchain.  Using target_os="ios" ensures that
        # the default toolchain is something different from
        # host_toolchain and thus that toolchain's toolchain_args()
        # block will be applied and set current_cpu correctly.
        'target_os="ios"',
        # build/config/ios/ios_sdk.gni will try to find some
        # XCode magic that won't exist.  This GN flag disables
        # the problematic code.
        'ios_enable_code_signing=false',
        ]

  gn_out_trusted = gn_out
  gn_out_irt = os.path.join(gn_out, 'irt_' + gn_arch_name)

  gn_cmd = [
      'gn.bat' if context.Windows() else 'gn',
      '--dotfile=../native_client/.gn', '--root=..',
      # Note: quotes are not needed around this space-separated
      # list of args.  The shell would remove them before passing
      # them to a program, and Python bypasses the shell.  Adding
      # quotes will cause an error because GN will see unexpected
      # double quotes.
      '--args=%s' % ' '.join(gn_gen_args),
      'gen', gn_out,
  ]

  gn_ninja_cmd = ['ninja', '-C', gn_out, '-v']
  if gn_arch_name not in ('x86', 'x64') and not context.Linux():
    # On non-Linux non-x86, we can only build the untrusted code.
    gn_ninja_cmd.append('untrusted')

  with Step('gn_compile' + out_suffix, status):
    Command(context, cmd=gn_cmd)
    Command(context, cmd=gn_ninja_cmd)

  return (gn_out_trusted, gn_out_irt)

def DoGNTest(status, context, using_gn, gn_perf_prefix, gn_step_suffix):
  if not using_gn:
    return

  gn_out_trusted, gn_out_irt = using_gn

  # Non-Linux can build non-x86 untrusted code, but can't build or run
  # the trusted code and so cannot test.
  if context['arch'] not in ('32', '64') and not context.Linux():
    return

  gn_sel_ldr = os.path.join(gn_out_trusted, 'sel_ldr')
  if context.Windows():
    gn_sel_ldr += '.exe'
  gn_extra = [
      'force_sel_ldr=' + gn_sel_ldr,
      'force_irt=' + os.path.join(gn_out_irt, 'irt_core.nexe'),
      'perf_prefix=' + gn_perf_prefix,
      ]
  if context.Linux():
    gn_extra.append('force_bootstrap=' +
                    os.path.join(gn_out_trusted, 'nacl_helper_bootstrap'))
  def RunGNTests(step_suffix, extra_scons_modes, suite_suffix):
    for suite in ['small_tests', 'medium_tests', 'large_tests']:
      with Step(suite + step_suffix + gn_step_suffix, status,
                halt_on_fail=False):
        SCons(context,
              mode=context['default_scons_mode'] + extra_scons_modes,
              args=[suite + suite_suffix] + gn_extra)
  if not context['use_glibc']:
    RunGNTests('', [], '')
  RunGNTests(' under IRT', ['nacl_irt_test'], '_irt')


def BuildScript(status, context):
  inside_toolchain = context['inside_toolchain']

  # Clean out build directories.
  with Step('clobber', status):
    RemoveSconsBuildDirectories()
    RemoveGypBuildDirectories()

  with Step('cleanup_temp', status):
    # Picking out drive letter on which the build is happening so we can use
    # it for the temp directory.
    if context.Windows():
      build_drive = os.path.splitdrive(os.path.abspath(__file__))[0]
      tmp_dir = os.path.join(build_drive, os.path.sep + 'temp')
      context.SetEnv('TEMP', tmp_dir)
      context.SetEnv('TMP', tmp_dir)
    else:
      tmp_dir = '/tmp'
    print 'Making sure %s exists...' % tmp_dir
    EnsureDirectoryExists(tmp_dir)
    print 'Cleaning up the contents of %s...' % tmp_dir
    # Only delete files and directories like:
    #   */nacl_tmp/*
    # TODO(bradnelson): Drop this after a bit.
    # Also drop files and directories like these to cleanup current state:
    #   */nacl_tmp*
    #   */nacl*
    #   83C4.tmp
    #   .org.chromium.Chromium.EQrEzl
    #   tmp_platform*
    #   tmp_mmap*
    #   tmp_pwrite*
    #   tmp_syscalls*
    #   workdir*
    #   nacl_chrome_download_*
    #   browserprofile_*
    #   tmp*
    file_name_re = re.compile(
        r'[\\/\A]('
        r'tmp_nacl[\\/].+|'
        r'tmp_nacl.+|'
        r'nacl.+|'
        r'[0-9a-fA-F]+\.tmp|'
        r'\.org\.chrom\w+\.Chrom\w+\.[^\\/]+|'
        r'tmp_platform[^\\/]+|'
        r'tmp_mmap[^\\/]+|'
        r'tmp_pwrite[^\\/]+|'
        r'tmp_syscalls[^\\/]+|'
        r'workdir[^\\/]+|'
        r'nacl_chrome_download_[^\\/]+|'
        r'browserprofile_[^\\/]+|'
        r'tmp[^\\/]+'
        r')$')
    file_name_filter = lambda fn: file_name_re.search(fn) is not None

    # Clean nacl_tmp/* separately, so we get a list of leaks.
    nacl_tmp = os.path.join(tmp_dir, 'nacl_tmp')
    if os.path.exists(nacl_tmp):
      for bot in os.listdir(nacl_tmp):
        bot_path = os.path.join(nacl_tmp, bot)
        print 'Cleaning prior build temp dir: %s' % bot_path
        sys.stdout.flush()
        if os.path.isdir(bot_path):
          for d in os.listdir(bot_path):
            path = os.path.join(bot_path, d)
            print 'Removing leftover: %s' % path
            sys.stdout.flush()
            RemovePath(path)
          os.rmdir(bot_path)
        else:
          print 'Removing rogue file: %s' % bot_path
          RemovePath(bot_path)
      os.rmdir(nacl_tmp)
    # Clean /tmp so we get a list of what's accumulating.
    TryToCleanContents(tmp_dir, file_name_filter)

    # Recreate TEMP, as it may have been clobbered.
    if 'TEMP' in os.environ and not os.path.exists(os.environ['TEMP']):
      os.makedirs(os.environ['TEMP'])

    # Mac has an additional temporary directory; clean it up.
    # TODO(bradnelson): Fix Mac Chromium so that these temp files are created
    #     with open() + unlink() so that they will not get left behind.
    if context.Mac():
      subprocess.call(
          "find /var/folders -name '.org.chromium.*' -exec rm -rfv '{}' ';'",
          shell=True)
      subprocess.call(
          "find /var/folders -name '.com.google.Chrome*' -exec rm -rfv '{}' ';'",
          shell=True)

  # Always update Clang.  On Linux and Mac, it's the default for the GN build.
  # It's also used for the Linux Breakpad build. On Windows, we do a second
  # Clang GN build.
  with Step('update_clang', status):
    Command(context, cmd=[sys.executable, '../tools/clang/scripts/update.py'])

  # Make sure our GN build is working.
  using_gn = DoGNBuild(status, context)
  using_gn_clang = False
  if (context.Windows() and
      not context['clang'] and
      context['arch'] in ('32', '64')):
    # On Windows, do a second GN build with is_clang=true.
    using_gn_clang = DoGNBuild(status, context, True)

  if context.Windows() and context['arch'] == '64':
    # On Windows, do a second pair of GN builds for 32-bit.  The 32-bit
    # bots can't do GN builds at all, because the toolchains GN uses don't
    # support 32-bit hosts.  The 32-bit binaries built here cannot be
    # tested on a 64-bit host, but compile time issues can be caught.
    DoGNBuild(status, context, False, '32')
    if not context['clang']:
      DoGNBuild(status, context, True, '32')

  # Just build both bitages of validator and test for --validator mode.
  if context['validator']:
    with Step('build ragel_validator-32', status):
      SCons(context, platform='x86-32', parallel=True, args=['ncval_new'])
    with Step('build ragel_validator-64', status):
      SCons(context, platform='x86-64', parallel=True, args=['ncval_new'])

    # Check validator trie proofs on both 32 + 64 bits.
    with Step('check validator proofs', status):
      SCons(context, platform='x86-64', parallel=False, args=['dfachecktries'])

    with Step('predownload validator corpus', status):
      Command(context,
          cmd=[sys.executable,
               'tests/abi_corpus/validator_regression_test.py',
               '--download-only'])

    with Step('validator_regression_test ragel x86-32', status,
        halt_on_fail=False):
      ValidatorTest(
          context, 'x86-32',
          'scons-out/opt-linux-x86-32/staging/ncval_new')
    with Step('validator_regression_test ragel x86-64', status,
        halt_on_fail=False):
      ValidatorTest(
          context, 'x86-64',
          'scons-out/opt-linux-x86-64/staging/ncval_new')

    return

  # Run checkdeps script to vet #includes.
  with Step('checkdeps', status):
    Command(context, cmd=[sys.executable, 'tools/checkdeps/checkdeps.py'])

  # On a subset of Linux builds, build Breakpad tools for testing.
  if context['use_breakpad_tools']:
    with Step('breakpad configure', status):
      Command(context, cmd=['mkdir', '-p', 'breakpad-out'])

      # Breakpad requires C++11, so use clang and the sysroot rather than
      # hoping that the host toolchain will provide support.
      configure_args = []
      if context.Linux():
        cc = 'CC=../../third_party/llvm-build/Release+Asserts/bin/clang'
        cxx = 'CXX=../../third_party/llvm-build/Release+Asserts/bin/clang++'
        flags = ''
        if context['arch'] == '32':
          flags += ' -m32'
          sysroot_arch = 'i386'
        else:
          flags += ' -m64'
          sysroot_arch = 'amd64'
        flags += (' --sysroot=../../build/linux/debian_sid_%s-sysroot' %
                  sysroot_arch)
        configure_args += [cc + flags, cxx + flags]
        configure_args += ['CXXFLAGS=-I../..',  # For third_party/lss
                           'LDFLAGS=-fuse-ld=lld']
      try:
       Command(context, cwd='breakpad-out',
              cmd=['bash', '../../breakpad/configure'] + configure_args)
      except:
        f = open(os.path.join('breakpad-out', 'config.log')).read()
        print f
        raise

    with Step('breakpad make', status):
      Command(context, cmd=['make', '-j%d' % context['max_jobs'],
                            # This avoids a broken dependency on
                            # src/third_party/lss files within the breakpad
                            # source directory.  We are not putting lss
                            # there, but using the -I switch above to
                            # find the lss in ../third_party instead.
                            'includelss_HEADERS=',
                            ],
              cwd='breakpad-out')

  # The main compile step.
  with Step('scons_compile', status):
    SCons(context, parallel=True, args=[])

  if context['coverage']:
    with Step('collect_coverage', status, halt_on_fail=True):
      SCons(context, args=['coverage'])
    with Step('summarize_coverage', status, halt_on_fail=False):
      SummarizeCoverage(context)
    slave_type = os.environ.get('BUILDBOT_SLAVE_TYPE')
    if slave_type != 'Trybot' and slave_type is not None:
      with Step('archive_coverage', status, halt_on_fail=True):
        ArchiveCoverage(context)
    return

  # Android bots don't run tests for now.
  if context['android']:
    return

  ### BEGIN tests ###
  if not context['use_glibc']:
    # Bypassing the IRT with glibc is not a supported case,
    # and in fact does not work at all with the new glibc.
    with Step('small_tests', status, halt_on_fail=False):
      SCons(context, args=['small_tests'])
    with Step('medium_tests', status, halt_on_fail=False):
      SCons(context, args=['medium_tests'])
    with Step('large_tests', status, halt_on_fail=False):
      SCons(context, args=['large_tests'])

  with Step('compile IRT tests', status):
    SCons(context, parallel=True, mode=['nacl_irt_test'])

  with Step('small_tests under IRT', status, halt_on_fail=False):
    SCons(context, mode=context['default_scons_mode'] + ['nacl_irt_test'],
          args=['small_tests_irt'])
  with Step('medium_tests under IRT', status, halt_on_fail=False):
    SCons(context, mode=context['default_scons_mode'] + ['nacl_irt_test'],
          args=['medium_tests_irt'])
  with Step('large_tests under IRT', status, halt_on_fail=False):
    SCons(context, mode=context['default_scons_mode'] + ['nacl_irt_test'],
          args=['large_tests_irt'])
  ### END tests ###

  ### BEGIN GN tests ###
  DoGNTest(status, context, using_gn, 'gn_', ' (GN)')
  DoGNTest(status, context, using_gn_clang, 'gn_clang_', '(GN, Clang)')
  ### END GN tests ###


def Main():
  # TODO(ncbray) make buildbot scripts composable to support toolchain use case.
  context = BuildContext()
  status = BuildStatus(context)
  ParseStandardCommandLine(context)
  SetupContextVars(context)
  if context.Windows():
    SetupWindowsEnvironment(context)
  elif context.Linux():
    if not context['android']:
      SetupLinuxEnvironment(context)
  elif context.Mac():
    # No setup to do for Mac.
    pass
  else:
    raise Exception("Unsupported platform.")
  RunBuild(BuildScript, status)


def TimedMain():
  start_time = time.time()
  try:
    Main()
  finally:
    time_taken = time.time() - start_time
    print 'RESULT BuildbotTime: total= %.3f minutes' % (time_taken / 60)


if __name__ == '__main__':
  TimedMain()
