#!/usr/bin/env python
# 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.

"""
This script runs every build as the first hook (See DEPS). If it detects that
the build should be clobbered, it will delete the contents of the build
directory.

A landmine is tripped when a builder checks out a different revision, and the
diff between the new landmines and the old ones is non-null. At this point, the
build is clobbered.

Before adding or changing a landmine consider the consequences of doing so.
Doing so will wipe out every output directory on every Chrome developer's
machine. This can be particularly problematic on Windows where the directory
deletion may well fail (locked files, command prompt in the directory, etc.),
and generated .sln and .vcxproj files will be deleted.

This output directory deletion will be repated when going back and forth across
the change that added the landmine, adding to the cost. There are usually less
troublesome alternatives.
"""

import difflib
import errno
import gyp_environment
import logging
import optparse
import os
import sys
import subprocess
import time

import clobber
import landmine_utils


def get_build_dir(src_dir):
  """
  Returns output directory absolute path dependent on build and targets.
  Examples:
    r'c:\b\build\slave\win\build\src\out'
    '/mnt/data/b/build/slave/linux/build/src/out'
    '/b/build/slave/ios_rel_device/build/src/out'

  Keep this function in sync with tools/build/scripts/slave/compile.py
  """
  if 'CHROMIUM_OUT_DIR' in os.environ:
    output_dir = os.environ.get('CHROMIUM_OUT_DIR').strip()
    if not output_dir:
      raise Error('CHROMIUM_OUT_DIR environment variable is set but blank!')
  else:
    output_dir = landmine_utils.gyp_generator_flags().get('output_dir', 'out')
  return os.path.abspath(os.path.join(src_dir, output_dir))


def clobber_if_necessary(new_landmines, src_dir):
  """Does the work of setting, planting, and triggering landmines."""
  out_dir = get_build_dir(src_dir)
  landmines_path = os.path.normpath(os.path.join(src_dir, '.landmines'))
  try:
    os.makedirs(out_dir)
  except OSError as e:
    if e.errno == errno.EEXIST:
      pass

  if os.path.exists(landmines_path):
    with open(landmines_path, 'r') as f:
      old_landmines = f.readlines()
    if old_landmines != new_landmines:
      old_date = time.ctime(os.stat(landmines_path).st_ctime)
      diff = difflib.unified_diff(old_landmines, new_landmines,
          fromfile='old_landmines', tofile='new_landmines',
          fromfiledate=old_date, tofiledate=time.ctime(), n=0)
      sys.stdout.write('Clobbering due to:\n')
      sys.stdout.writelines(diff)
      sys.stdout.flush()

      clobber.clobber(out_dir)

  # Save current set of landmines for next time.
  with open(landmines_path, 'w') as f:
    f.writelines(new_landmines)


def process_options():
  """Returns an options object containing the configuration for this script."""
  parser = optparse.OptionParser()
  parser.add_option(
      '-s', '--landmine-scripts', action='append',
      help='Path to the script which emits landmines to stdout. The target '
           'is passed to this script via option -t. Note that an extra '
           'script can be specified via an env var EXTRA_LANDMINES_SCRIPT.')
  parser.add_option('-d', '--src-dir',
      help='Path of the source root dir. Overrides the default location of the '
           'source root dir when calculating the build directory.')
  parser.add_option('-v', '--verbose', action='store_true',
      default=('LANDMINES_VERBOSE' in os.environ),
      help=('Emit some extra debugging information (default off). This option '
          'is also enabled by the presence of a LANDMINES_VERBOSE environment '
          'variable.'))

  options, args = parser.parse_args()

  if args:
    parser.error('Unknown arguments %s' % args)

  logging.basicConfig(
      level=logging.DEBUG if options.verbose else logging.ERROR)

  if options.src_dir:
    if not os.path.isdir(options.src_dir):
      parser.error('Cannot find source root dir at %s' % options.src_dir)
    logging.debug('Overriding source root dir. Using: %s', options.src_dir)
  else:
    options.src_dir = \
        os.path.dirname(os.path.dirname(os.path.realpath(__file__)))

  if not options.landmine_scripts:
    options.landmine_scripts = [os.path.join(options.src_dir, 'build',
                                             'get_landmines.py')]

  extra_script = os.environ.get('EXTRA_LANDMINES_SCRIPT')
  if extra_script:
    options.landmine_scripts += [extra_script]

  return options


def main():
  options = process_options()

  gyp_environment.SetEnvironment()

  landmines = []
  for s in options.landmine_scripts:
    proc = subprocess.Popen([sys.executable, s], stdout=subprocess.PIPE)
    output, _ = proc.communicate()
    landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
  clobber_if_necessary(landmines, options.src_dir)

  return 0


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