# Copyright 2014 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.

import contextlib
import json
import os
import re

from recipe_engine import recipe_api
from recipe_engine import util as recipe_util

class FilterApi(recipe_api.RecipeApi):
  def __init__(self, **kwargs):
    super(FilterApi, self).__init__(**kwargs)
    self._test_targets = []
    self._compile_targets = []
    self._paths = []

  def __is_path_in_regex_list(self, path, regexes):
    """Returns true if |path| matches any of the regular expressions in
    |regexes|."""
    for regex in regexes:
      match = regex.match(path)
      if match and match.end() == len(path):
        return regex.pattern
    return False

  @property
  def test_targets(self):
    """Returns the set of targets passed to does_patch_require_compile() that
    are affected by the set of files that have changed."""
    return self._test_targets

  @property
  def compile_targets(self):
    """Returns the set of targets that need to be compiled based on the set of
    files that have changed."""
    return self._compile_targets

  @property
  def paths(self):
    """Returns the paths that have changed in this patch."""
    return self._paths

  def _load_analyze_config(self, file_name):
    config_path = self.m.path.join('testing', 'buildbot', file_name)
    step_result = self.m.json.read(
      'read filter exclusion spec',
      self.m.path['checkout'].join(config_path),
      step_test_data=lambda: self.m.json.test_api.output({
          'base': {
            'exclusions': [],
          },
          'chromium': {
            'exclusions': [],
          },
          'ios': {
            'exclusions': [],
          },
        })
      )
    step_result.presentation.step_text = 'path: %r' % config_path
    return step_result.json.output

  def does_patch_require_compile(self,
                                 affected_files,
                                 test_targets=None,
                                 additional_compile_targets=None,
                                 additional_names=None,
                                 config_file_name='trybot_analyze_config.json',
                                 use_mb=False,
                                 mb_mastername=None,
                                 mb_buildername=None,
                                 mb_config_path=None,
                                 build_output_dir=None,
                                 cros_board=None,
                                 **kwargs):
    """Check to see if the affected files require a compile or tests.

    Args:
      affected_files: list of files affected by the current patch; paths
                      should only use forward slashes ("/") on all platforms
      test_targets: the possible set of executables that are desired to run.
                    When done, test_targets() returns the subsetset of targets
                    that are affected by the files that have changed.
      additional_compile_targets: any targets to compile in addition to
                                  the test_targets.
      additional_names: additional top level keys to look up exclusions in,
                        see |config_file_name|.
      conconfig_file_name: the config file to look up exclusions in.
      mb_mastername: the mastername to pass over to run MB.
      mb_buildername: the buildername to pass over to run MB.
      mb_config_path: the path to the MB config file.

    Within the file we concatenate "base.exclusions" and
    "|additional_names|.exclusions" (if |additional_names| is not none) to
    get the full list of exclusions.

    The exclusions should be a list of Python regular expressions (as strings).

    If any of the files in the current patch match one of the values in
    we assume everything needs to be compiled and tested.

    If an error occurs, an exception is raised. Otherwise, after the
    call completes the results can be obtained from self.compile_targets()
    and self.test_targets().

    To run MB, we need to use the actual mastername and buildername we're
    running on, and not those of the continuous builder the trybot may be
    configured to match, because a trybot may be configured with different MB
    settings.
    However, recipes used by Findit for culprit finding may override the
    defaults with `mb_mastername` and `mb_buildername` to exactly match a given
    continuous builder.
    """

    names = ['base']
    if additional_names:
      names.extend(additional_names)

    config_contents = self._load_analyze_config(config_file_name)
    exclusions = []
    ignores = []
    for name in names:
      exclusions.extend(config_contents[name].get('exclusions', []))
      ignores.extend(config_contents[name].get('ignores', []))

    test_targets = test_targets or []
    additional_compile_targets = additional_compile_targets or []
    all_targets = sorted(set(test_targets) | set(additional_compile_targets))
    self._test_targets = []
    self._compile_targets = []
    self._paths = affected_files

    analyze_input = {
        'files': self.paths,
        'test_targets': test_targets,
        'additional_compile_targets': additional_compile_targets,
    }

    # Check the path of each file against the exclusion list. If found, we
    # should ignore the dependency check, because it might be wrong.
    exclusion_regexs = [re.compile(exclusion) for exclusion in exclusions]
    ignore_regexs = [re.compile(ignore) for ignore in ignores]
    ignored = True
    matched_exclusion = False
    for path in self.paths:
      first_match = self.__is_path_in_regex_list(path, exclusion_regexs)
      if first_match:
        matched_exclusion = True

      if not self.__is_path_in_regex_list(path, ignore_regexs):
        ignored = False

    if ignored:
      analyze_result = 'No compile necessary (all files ignored)'
      self.m.python.succeeding_step('analyze', analyze_result)
      self._report_analyze_result(analyze_input, {'status': analyze_result})
      return

    test_output = {
        'status': 'No dependency',
        'compile_targets': [],
        'test_targets': [],
    }

    env = {}

    if use_mb:
      # Ensure that mb runs in a clean environment to avoid
      # picking up any GYP_DEFINES accidentally.
      if self.m.chromium.c.env.FORCE_MAC_TOOLCHAIN:
        env['FORCE_MAC_TOOLCHAIN'] = \
            self.m.chromium.c.env.FORCE_MAC_TOOLCHAIN

    # If building for CrOS, execute through the "chrome_sdk" wrapper. This will
    # override GYP environment variables, so we'll refrain from defining them
    # to avoid confusing output.
    cwd = None
    optional_system_python = contextlib.contextmanager(
        lambda: (x for x in [None]))()
    if cros_board:
      kwargs['wrapper'] = self.m.chromium.get_cros_chrome_sdk_wrapper()
      cwd = self.m.context.cwd or self.m.path['checkout']
      optional_system_python = self.m.chromite.with_system_python()
    elif not use_mb:
      env.update(self.m.chromium.c.gyp_env.as_jsonish())
    env['GOMA_SERVICE_ACCOUNT_JSON_FILE'] = \
        self.m.goma.service_account_json_path

    with optional_system_python:
      with self.m.context(cwd=cwd, env=env):
        if use_mb:
          mb_mastername = mb_mastername or self.m.properties['mastername']
          mb_buildername = mb_buildername or self.m.properties['buildername']
          mb_arguments = [
              'analyze',
              '-m', mb_mastername,
              '-b', mb_buildername,
          ]
          if mb_config_path:
            mb_arguments += ['-f', mb_config_path]
          mb_arguments += [
              '-v',
              build_output_dir,
              self.m.json.input(analyze_input),
              self.m.json.output()
          ]
          step_result = self.m.python(
              'analyze',
              self.m.path['checkout'].join('tools', 'mb', 'mb.py'),
              args=mb_arguments,
              step_test_data=lambda: self.m.json.test_api.output(
                test_output),
              **kwargs)
        else:
          step_result = self.m.python(
              'analyze',
              self.m.path['checkout'].join('build', 'gyp_chromium'),
              args=['--analyzer',
                    self.m.json.input(analyze_input),
                    self.m.json.output()],
              step_test_data=lambda: self.m.json.test_api.output(
                test_output),
              **kwargs)

    try:
      if 'error' in step_result.json.output:
        step_result.presentation.step_text = ('Error: ' +
            step_result.json.output['error'])
        step_result.presentation.status = self.m.step.FAILURE
        raise self.m.step.StepFailure(
            'Error: ' + step_result.json.output['error'])

      if 'invalid_targets' in step_result.json.output:
        raise self.m.step.StepFailure('Error, following targets were not '
            'found: ' + ', '.join(step_result.json.output['invalid_targets']))

      if matched_exclusion:
        analyze_result = 'Analyze disabled: matched exclusion'
        # TODO(phajdan.jr): consider using plain api.step here, not python.
        step_result = self.m.python.succeeding_step('analyze_matched_exclusion',
            analyze_result)
        step_result.presentation.logs.setdefault('excluded_files', []).append(
            '%s (regex = \'%s\')' % (path, first_match))
        self._compile_targets = sorted(all_targets)
        self._test_targets = sorted(test_targets)
        self._report_analyze_result(analyze_input, {'status': analyze_result})
      elif (step_result.json.output['status'] in (
          'Found dependency', 'Found dependency (all)')):
        self._compile_targets = step_result.json.output['compile_targets']
        self._test_targets = step_result.json.output['test_targets']

        # TODO(dpranke) crbug.com/557505 - we need to not prune meta
        # targets that are part of 'test_targets', because otherwise
        # we might not actually build all of the binaries needed for
        # a given test, even if they aren't affected by the patch.
        # Until the GYP code is updated, we will merge the returned
        # test_targets into compile_targets to be safe.
        self._compile_targets = sorted(set(self._compile_targets +
                                           self._test_targets))
      else:
        step_result.presentation.step_text = 'No compile necessary'
    finally:
      if not matched_exclusion:
        self._report_analyze_result(analyze_input, step_result.json.output)

  # TODO(phajdan.jr): Merge with does_patch_require_compile.
  def analyze(self, affected_files, test_targets, additional_compile_targets,
              config_file_name, mb_mastername=None, mb_buildername=None,
              mb_config_path=None, additional_names=None):
    """Runs "analyze" step to determine targets affected by the patch.

    Returns a tuple of:
      - list of targets that are needed to run tests (see filter recipe module)
      - list of targets that need to be compiled (see filter recipe module)"""

    if additional_names is None:
      additional_names = ['chromium']

    use_mb = (self.m.chromium.c.project_generator.tool == 'mb')
    build_output_dir = '//out/%s' % self.m.chromium.c.build_config_fs
    self.does_patch_require_compile(
        affected_files,
        test_targets=test_targets,
        additional_compile_targets=additional_compile_targets,
        additional_names=additional_names,
        config_file_name=config_file_name,
        use_mb=use_mb,
        mb_mastername=mb_mastername,
        mb_buildername=mb_buildername,
        mb_config_path=mb_config_path,
        build_output_dir=build_output_dir,
        cros_board=self.m.chromium.c.TARGET_CROS_BOARD)

    compile_targets = self.compile_targets[:]

    # Emit more detailed output useful for debugging.
    analyze_details = {
        'test_targets': test_targets,
        'additional_compile_targets': additional_compile_targets,
        'self.m.filter.compile_targets': self.compile_targets,
        'self.m.filter.test_targets': self.test_targets,
        'compile_targets': compile_targets,
    }
    with contextlib.closing(recipe_util.StringListIO()) as listio:
      json.dump(analyze_details, listio, indent=2, sort_keys=True)
    step_result = self.m.step.active_result
    step_result.presentation.logs['analyze_details'] = listio.lines

    return self.test_targets, compile_targets

  def _report_analyze_result(self, analyze_input, analyze_output):
    # TODO(phajdan.jr): send data to event_mon.
    return
