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

from recipe_engine import recipe_api


class IsolateApi(recipe_api.RecipeApi):
  """APIs for interacting with isolates."""

  def __init__(self, **kwargs):
    super(IsolateApi, self).__init__(**kwargs)
    self._isolate_server = 'https://isolateserver.appspot.com'
    self._isolated_tests = {}

  @property
  def isolate_server(self):
    """URL of Isolate server to use, default is a production one."""
    return self._isolate_server

  @isolate_server.setter
  def isolate_server(self, value):
    """Changes URL of Isolate server to use."""
    self._isolate_server = value

  def set_isolate_environment(self, config):
    """Modifies the config to include isolate related GYP_DEFINES.

    Modifies the passed Config (which should generally be api.chromium.c) to set
    up the appropriate GYP_DEFINES to prepare all necessary files to do this
    after compile. This must be called early in your recipe; definitely before
    the checkout and runhooks steps.
    """
    config.gyp_env.GYP_DEFINES['test_isolation_mode'] = 'prepare'

  def clean_isolated_files(self, build_dir):
    """Cleans out all *.isolated files from the build directory in
    preparation for the compile. Needed in order to ensure isolates
    are rebuilt properly because their dependencies are currently not
    completely described to gyp.

    Should be invoked before compilation in both 'archive' or 'prepare' modes
    (see 'set_isolate_environment').
    """
    self.m.python(
      'clean isolated files',
      self.resource('find_isolated_tests.py'),
      [
        '--build-dir', build_dir,
        '--clean-isolated-files'
      ])

  def find_isolated_tests(self, build_dir, targets=None, **kwargs):
    """Returns a step which finds all *.isolated files in a build directory.

    Useful only with 'archive' isolation mode (see 'set_isolate_environment').
    In 'prepare' mode use 'isolate_tests' instead.

    Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes
    build property. This implies this step can currently only be run once
    per recipe.

    If |targets| is None, the step will use all *.isolated files it finds.
    Otherwise, it will verify that all |targets| are found and will use only
    them. If some expected targets are missing, will abort the build.
    """
    step_result = self.m.python(
      'find isolated tests',
      self.resource('find_isolated_tests.py'),
      [
        '--build-dir', build_dir,
        '--output-json', self.m.json.output(),
      ],
      step_test_data=lambda: (self.test_api.output_json(targets)),
      **kwargs)

    assert isinstance(step_result.json.output, dict)
    self._isolated_tests = step_result.json.output
    if targets is not None and (
            step_result.presentation.status != self.m.step.FAILURE):
      found = set(step_result.json.output)
      expected = set(targets)
      if found >= expected:
        # Limit result only to |expected|.
        self._isolated_tests = {
          target: step_result.json.output[target] for target in expected
        }
      else:
        # Some expected targets are missing? Fail the step.
        step_result.presentation.status = self.m.step.FAILURE
        step_result.presentation.logs['missing.isolates'] = (
            ['Failed to find *.isolated files:'] + list(expected - found))
    step_result.presentation.properties['swarm_hashes'] = self._isolated_tests
    # No isolated files found? That looks suspicious, emit warning.
    if (not self._isolated_tests and
        step_result.presentation.status != self.m.step.FAILURE):
      step_result.presentation.status = self.m.step.WARNING

  def isolate_tests(self, build_dir, targets=None, verbose=False,
                    set_swarm_hashes=True, **kwargs):
    """Archives prepared tests in |build_dir| to isolate server.

    Works only if Chromium was compiled with test_isolation_mode=='prepare'. See
    set_isolate_environment(). In that mode src/tools/isolate_driver.py is
    invoked by ninja during compilation to produce *.isolated.gen.json files
    that describe how to archive tests.

    This step then uses *.isolated.gen.json files to actually performs the
    archival. By archiving all tests at once it is able to reduce the total
    amount of work. Tests share many common files, and such files are processed
    only once.

    Assigns the dict {target name -> *.isolated file hash} to the swarm_hashes
    build property (also accessible as 'isolated_tests' property). This implies
    this step can currently only be run once per recipe.
    """
    # TODO(vadimsh): Always require |targets| to be passed explicitly. Currently
    # chromium_trybot, blink_trybot and swarming/canary recipes rely on targets
    # autodiscovery. The code path in chromium_trybot that needs it is being
    # deprecated in favor of to *_ng builders, that pass targets explicitly.
    if targets is None:
      # Ninja builds <target>.isolated.gen.json files via isolate_driver.py.
      paths = self.m.file.glob(
          'find isolated targets',
          build_dir.join('*.isolated.gen.json'),
          test_data=[
            build_dir.join('dummy_target_%d.isolated.gen.json' % i)
            for i in (1, 2)
          ])
      targets = []
      for p in paths:
        name = self.m.path.basename(p)
        assert name.endswith('.isolated.gen.json'), name
        targets.append(name[:-len('.isolated.gen.json')])

    # No isolated tests found.
    if not targets:  # pragma: no cover
      return

    input_files = [build_dir.join('%s.isolated.gen.json' % t) for t in targets]
    try:
      # TODO(vadimsh): Differentiate between bad *.isolate and upload errors.
      # Raise InfraFailure on upload errors.
      args = [
        self.m.swarming_client.path,
        'batcharchive',
        '--dump-json', self.m.json.output(),
        '--isolate-server', self._isolate_server,
      ] + (['--verbose'] if verbose else []) + input_files
      return self.m.python(
          'isolate tests', self.resource('isolate.py'), args,
          step_test_data=lambda: (self.test_api.output_json(targets)),
          **kwargs)
    finally:
      step_result = self.m.step.active_result
      self._isolated_tests = step_result.json.output
      if self._isolated_tests:
        presentation = step_result.presentation
        if set_swarm_hashes:
          presentation.properties['swarm_hashes'] = self._isolated_tests
        missing = sorted(
            t for t, h in self._isolated_tests.iteritems() if not h)
        if missing:
          step_result.presentation.logs['failed to isolate'] = (
            ['Failed to isolate following targets:'] +
            missing +
            ['', 'See logs for more information.']
          )
          for k in missing:
            self._isolated_tests.pop(k)

  @property
  def isolated_tests(self):
    """The dictionary of 'target name -> isolated hash' for this run.

    These come either from the incoming swarm_hashes build property,
    or from calling find_isolated_tests, above, at some point during the run.
    """
    hashes = self.m.properties.get('swarm_hashes', self._isolated_tests)
    # Be robust in the case where swarm_hashes is an empty string
    # instead of an empty dictionary, or similar.
    if not hashes:
      return {} # pragma: no covergae
    return {
      k.encode('ascii'): v.encode('ascii')
      for k, v in hashes.iteritems()
    }

  @property
  def _run_isolated_path(self):
    """Returns the path to run_isolated.py."""
    return self.m.swarming_client.path.join('run_isolated.py')

  def run_isolated(self, name, isolate_hash, args=None, **kwargs):
    """Runs an isolated test."""
    cmd = [
        '--isolated', isolate_hash,
        '-I', self.isolate_server,
        '--verbose',
    ]
    if args:
      cmd.append('--')
      cmd.extend(args)
    self.m.python(name, self._run_isolated_path, cmd, **kwargs)

  def remove_build_metadata(self):
    """Removes the build metadata embedded in the build artifacts."""
    args = [
        '--build-dir', self.m.chromium.output_dir,
    ]
    # Turn the failures during this step into warnings, it's a best effort step
    # that shouldn't break the build for now.
    try:
      self.m.python('remove_build_metadata',
                    self.m.path.join(self.m.path['checkout'],
                                     'tools',
                                     'determinism',
                                     'remove_build_metadata.py'),
                    args=args,
                    cwd=self.m.path['slave_build'])
    except self.m.step.StepFailure:
      step_result = self.m.step.active_result
      step_result.presentation.status = self.m.step.WARNING

  def compare_build_artifacts(self, first_dir, second_dir):
    """Compare the artifacts from 2 builds."""
    args = [
        '--first-build-dir', first_dir,
        '--second-build-dir', second_dir,
        '--target-platform', self.m.chromium.c.TARGET_PLATFORM
    ]
    self.m.python('compare_build_artifacts',
                  self.m.path.join(self.m.path['checkout'],
                                   'tools',
                                   'determinism',
                                   'compare_build_artifacts.py'),
                  args=args,
                  cwd=self.m.path['slave_build'])
