# Copyright 2016 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 google.protobuf import struct_pb2, json_format

from recipe_engine.post_process import (
    DoesNotRunRE,
    DropExpectation,
    MustRun,
    MustRunRE,
    StatusException,
    StatusFailure,
    StatusSuccess,
)

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2

from PB.recipes.dart.dart.gclient import Gclient

PROPERTIES = Gclient

DEPS = [
    'bisect_build',
    'dart',
    'depot_tools/gitiles',
    'depot_tools/tryserver',
    'depot_tools/osx_sdk',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]


TEST_MATRIX = {
  "filesets": {
    "fileset1": "[]",
    "nameoffileset": "[]"
  },
  "global": {
    "chrome": "66.0.3359.139",
    "firefox": "60.0.1"
  },
  "builder_configurations": [
    {
      "builders": [
        "dart2js-win-debug-x64-firefox",
      ],
      "meta": {},
      "steps": [{
        "name": "Build",
        "script": "tools/build.py",
        "arguments": ["foo", "--bar"],
        "shards": 1
      }, {
        "name": "Test-step 1",
        "script": "tools/test.py",
        "arguments": ["foo", "--bar", "-e co19", "language_2"],
      }, {
        "name": "Test-step 2",
        "arguments": ["foo", "--bar", "-mdebug",
                      "-n${runtime}-foo-${mode}-${arch}-bar"],
      }]
    }
  ]
}


def _is_infra_failure(api, failure):
  return (isinstance(failure, api.step.InfraFailure) or
          api.dart.has_infra_failure(failure))


def _compute_failure_reason(api, failure):
  assert not failure or not _is_infra_failure(api, failure)
  return failure.reason if failure else api.bisect_build.REASON_SUCCESS


def _schedule_bisection(api, failure=None):
  if not api.bisect_build.is_enabled:
    # This builder is not configured to use bisection.
    return
  if _is_infra_failure(api, failure):
    # TODO(karlklose): fan out on infra failures during bisection and consider
    #                  starting a bisection for some kinds of infra failures.
    return
  elif api.bisect_build.is_bisecting() or failure:
    reason = _compute_failure_reason(api, failure)
    api.bisect_build.schedule("https://dart.googlesource.com/sdk", reason)


def RunSteps(api, properties):
  # Override analyzer cache location to make analyzer runs hermetic.
  env = {'ANALYZER_STATE_LOCATION_OVERRIDE':
      api.path['cleanup'].join('analysis-cache')}
  try:
    with api.osx_sdk('mac'), api.context(env=env):
      _run_steps_impl(api, properties)
  except api.step.StepFailure as failure:
    _schedule_bisection(api, failure)
    raise
  _schedule_bisection(api)


def _run_steps_impl(api, properties):
  clobber = api.properties.get('clobber', False)
  api.dart.checkout(
      clobber=clobber,
      custom_vars=json_format.MessageToDict(properties.custom_vars))
  api.dart.kill_tasks()

  try:
    api.dart.test(test_data=TEST_MATRIX)
  finally:
    api.dart.kill_tasks()


RESULT_DATA = (
    '{"name":"test_foo"'
    ',"configuration":"config_bar","suite":"suite_baz",'
    '"test_name":"Language/Classes/Abstract_Instance_Members/inherited_t01",'
    '"time_ms":451,"result":"CompileTimeError","expected":"CompileTimeError",'
    '"matches":true,"commit_time":1551185312,'
    '"commit_hash":"f0042a32250a8a6193e6d07e2b6508b13f43c864",'
    '"build_number":"2404","builder_name":"vm-kernel-linux-product-x64",'
    '"bot_name":"trusty-dart-68765ebb-us-central1-b-2ls0","flaky":false,'
    '"previous_flaky":false,"previous_result":"CompileTimeError",'
    '"previous_commit_hash":"f0042a32250a8a6193e6d07e2b6508b13f43c864",'
    '"previous_commit_time":1551185312,"previous_build_number":2403,'
    '"changed":false}\n')

TESTED_REVISION = '1a2b3c4d'


def GenTests(api):
  yield api.test(
      'builders/dart2js-win-debug-x64-firefox-try',
      api.buildbucket.try_build(
          builder='dart2js-win-debug-x64-firefox-try',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart'),
      api.properties(
          Gclient(
              custom_vars=json_format.ParseDict({
                  'download_firefox': True,
              }, struct_pb2.Struct()))),
      api.step_data('add fields to result records',
                    api.raw_io.output_text(RESULT_DATA)),
  )

  yield api.test(
      'successful-build-does-not-start-bisection',
      api.buildbucket.ci_build(
          builder='dart2js-win-debug-x64-firefox',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart',
          revision=TESTED_REVISION),
      api.properties(bisection_enabled=True),
      api.step_data('add fields to result records',
                    api.raw_io.output_text(RESULT_DATA)),
      api.post_process(DoesNotRunRE, 'schedule bisect (.*)'),
      api.post_process(StatusSuccess),
  )

  yield api.test(
      'infra-failure-does-not-start-bisection',
      api.buildbucket.ci_build(
          builder='dart2js-win-debug-x64-firefox',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart',
          revision=TESTED_REVISION),
      api.properties(bisection_enabled=True),
      api.step_data('add fields to result records',
                    api.raw_io.output_text(RESULT_DATA)),
      # Create an infra-failure in the test results step
      api.step_data('test results', retcode=2),
      api.post_process(DoesNotRunRE, 'schedule bisect (.*)'),
      api.post_process(StatusException),
  )

  yield api.test(
      'toplevel-infra-failure-does-not-start-bisection',
      api.buildbucket.ci_build(
          # Specifies a builder that is not in the test matrix:
          builder='undefined-builder-name',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart',
          revision=TESTED_REVISION),
      api.properties(bisection_enabled=True),
      api.post_process(DoesNotRunRE, 'schedule bisect (.*)'),
      api.post_process(StatusException),
  )

  yield api.test(
      'failing-test-step-starts-bisection',
      api.buildbucket.ci_build(
          builder='dart2js-win-debug-x64-firefox',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart',
          build_number=4711,
          revision=TESTED_REVISION),
      api.properties(bisection_enabled=True),
      api.step_data('add fields to result records',
                    api.raw_io.output_text(RESULT_DATA)),
      # Create a successful base build for the bisection
      # (see bisect_build/test_api.py)
      api.bisect_build.fetch_previous_builds([
          api.bisect_build.build('foo', 4710,
                                 '2d72510e447ab60a9728aeea2362d8be2cbd7789')
      ]) +
      # Create a fake gitiles log for the bisection algorithm (see gitiles/test_api.py)
      api.step_data(
          'gitiles log: 2d72510e447ab60a9728aeea2362d8be2cbd7789..%s' %
          TESTED_REVISION, api.gitiles.make_log_test_data('main')),
      # Make test step fail by failing the 'test results' step
      api.step_data('test results', retcode=1),
      api.post_process(MustRunRE, 'schedule bisect .*'),
      api.post_process(StatusFailure),
  )

  yield api.test(
      'different-failure-in-bisection-schedules-two-bisection-builds',
      api.buildbucket.ci_build(
          builder='dart2js-win-debug-x64-firefox',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart',
          revision=TESTED_REVISION),
      api.properties(
          bisection_enabled=True,
          bisect_newer=['a', 'b', 'c'],
          bisect_older=['c', 'd', 'e'],
          bisect_base_build=4711,
          bisect_reason="Step('Build') (retcode: 1)",
      ),
      # Make build step fail by failing the 'test results' step
      api.step_data('test results', retcode=1),
      api.post_process(MustRun, 'schedule bisect (b)'),
      api.post_process(MustRun, 'schedule bisect (d)'),
      api.post_process(StatusFailure),
      api.post_process(DropExpectation),
  )
