# 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 import recipe_api

from recipe_engine.post_process import DoesNotRunRE, MustRun, 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/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 bisection_is_enabled(api):
  return api.properties.get('bisection_enabled', False)


def schedule_bisection(api, failure=None):
  if not bisection_is_enabled(api):
    # This builder is not configured to use bisection.
    return
  if (isinstance(failure, api.step.InfraFailure) or
      api.dart.has_infra_failure(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:
    # TODO(karlklose): distinguish between test failures and build failures (and
    #                  start additional bisection runs for different failures).
    reason = "FAILURE" if failure else api.bisect_build.REASON_SUCCESS
    api.bisect_build.schedule(
        "https://dart.googlesource.com/sdk", reason, is_experimental=True)


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 = 'clobber' in api.properties
  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-build-starts-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 a successful base build for the bisection (see buildbucket/test_api.py)
      api.buildbucket.simulated_search_results(
          [
              api.buildbucket.ci_build_message(
                  status='SUCCESS', build_number=4711),
          ],
          step_name='fetch previous build'),
      # 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('master')),
      # Make build fail by failing the 'test results' step
      api.step_data('test results', retcode=1),
      api.post_process(
          MustRun,
          'schedule bisect (f4d35da881f8fd329a4d3e01dd78b66a502d5c49)'),
      api.post_process(StatusFailure),
  )
