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


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),
  )
