# Copyright 2020 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.
#
# Recipe to run shard + subshard tests for the Flutter SDK repository.
# This recipe will run a single shard and will be used by flutter/flutter.py.
import contextlib

from RECIPE_MODULES.flutter.flutter_bcid.api import BcidStage

DEPS = [
    'flutter/flutter_bcid',
    'flutter/flutter_deps',
    'flutter/logs_util',
    'flutter/os_utils',
    'flutter/osx_sdk',
    'flutter/repo_util',
    'flutter/retry',
    'flutter/test_utils',
    'flutter/token_util',
    'recipe_engine/context',
    'recipe_engine/defer',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
    'recipe_engine/file',
]

# Default timeouts for framework tests.
HOSTONLY_TIMEOUT_SECS = 30 * 60
DEVICELAB_TIMEOUT_SECS = 10 * 60


def RunShard(api, env, env_prefixes, checkout_path):
  with api.context(env=env, env_prefixes=env_prefixes, cwd=checkout_path):
    cmd_list = [
        'dart', '--enable-asserts',
        checkout_path.join('dev', 'bots', 'test.dart')
    ]
    if env.get('LOCAL_WEB_SDK'):
      cmd_list.extend(['--local-web-sdk', env.get('LOCAL_WEB_SDK')])

    # Default timeout for tasks in either devicelab or hostonly.
    default_timeout_secs = DEVICELAB_TIMEOUT_SECS if api.os_utils.is_devicelab(
    ) else HOSTONLY_TIMEOUT_SECS
    deps_timeout_secs = api.properties.get(
        'test_timeout_secs'
    ) or default_timeout_secs
    env['GCP_PROJECT'] = 'flutter-infra'
    with api.context(env=env, env_prefixes=env_prefixes):
      api.test_utils.run_test(
          'run test.dart for %s shard and subshard %s' %
          (api.properties.get('shard'), api.properties.get('subshard')),
          cmd_list,
          timeout_secs=deps_timeout_secs
      )
      api.logs_util.show_logs_stdout(checkout_path.join('error.log'))
      api.logs_util.upload_test_metrics(
          checkout_path.join('test_results.json'), '%s_%s' %
          (api.properties.get('shard'), api.properties.get('subshard'))
      )


def RunSteps(api):
  api.flutter_bcid.report_stage(BcidStage.START.value)
  # Collect memory/cpu/process before task execution.
  api.os_utils.collect_os_info()

  # If on macOS, reset Xcode in case a previous build failed to do so.
  api.osx_sdk.reset_xcode()

  api.os_utils.print_pub_certs()

  checkout_path = api.path['start_dir'].join('flutter')
  api.flutter_bcid.report_stage(BcidStage.FETCH.value)
  api.repo_util.checkout(
      'flutter',
      checkout_path=checkout_path,
      url=api.properties.get('git_url'),
      ref=api.properties.get('git_ref')
  )

  env, env_prefixes = api.repo_util.flutter_environment(checkout_path)
  deps = api.properties.get('dependencies', [])
  api.flutter_deps.required_deps(env, env_prefixes, deps)
  # Add shard, subshard, and test scope.
  env['SHARD'] = api.properties.get('shard')
  env['SUBSHARD'] = api.properties.get('subshard')
  env['REDUCED_TEST_SET'] = api.properties.get('reduced_test_set', False)

  with api.context(env=env, env_prefixes=env_prefixes, cwd=checkout_path):
    # Dependencies timeout.
    deps_timeout_secs = 300
    api.retry.step(
        'download dependencies', ['flutter', 'update-packages', '-v'],
        max_attempts=2,
        infra_step=True
    )
    with contextlib.ExitStack() as exit_stack:
      api.flutter_deps.enter_contexts(
          exit_stack, api.properties.get('contexts', []), env, env_prefixes
      )
      # Load local engine information if available.
      api.flutter_deps.flutter_engine(env, env_prefixes)
      deferred = []
      deferred.append(
          api.defer(api.step, 'flutter doctor', ['flutter', 'doctor', '-v'])
      )
      deferred.append(
          api.defer(RunShard, api, env, env_prefixes, checkout_path)
      )
      # This is to clean up leaked processes.
      deferred.append(api.defer(api.os_utils.kill_processes))
      # Collect memory/cpu/process after task execution.
      deferred.append(api.defer(api.os_utils.collect_os_info))
      api.defer.collect(deferred)


def GenTests(api):
  for should_run_reduced in (True, False):
    yield api.test(
        'no_requirements%s' % ('_reduced' if should_run_reduced else ''),
        api.repo_util.flutter_environment_data(),
        api.properties(reduced_test_set=should_run_reduced)
    )
    yield api.test(
        'android_sdk%s' % ('_reduced' if should_run_reduced else ''),
        api.repo_util.flutter_environment_data(),
        api.properties(
            dependencies=[{'dependency': 'android_sdk'}],
            android_sdk=True,
            android_sdk_preview_license='abc',
            android_sdk_license='cde',
            reduced_test_set=should_run_reduced
        )
    )
    yield api.test(
        'web_engine%s' % ('_reduced' if should_run_reduced else ''),
        api.repo_util.flutter_environment_data(),
        api.properties(
            local_web_sdk_cas_hash='abceqwe',
            reduced_test_set=should_run_reduced
        )
    )
    yield api.test(
        'xcode%s' % ('_reduced' if should_run_reduced else ''),
        api.repo_util.flutter_environment_data(),
        api.properties(
            **{'$flutter/osx_sdk': {'sdk_version': 'deadbeef',}},
            reduced_test_set=should_run_reduced
        )
    )
