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

from recipe_engine.recipe_api import Property

PYTHON_VERSION_COMPATIBILITY = 'PY3'

DEPS = [
    'depot_tools/gsutil',
    'flutter/flutter_deps',
    'flutter/logs_util',
    'flutter/os_utils',
    'flutter/osx_sdk',
    'flutter/repo_util',
    'flutter/retry',
    'flutter/test_utils',
    'flutter/token_util',
    'fuchsia/git',
    'recipe_engine/buildbucket',
    'recipe_engine/cas',
    'recipe_engine/context',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/platform',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/runtime',
    'recipe_engine/step',
    'recipe_engine/swarming',
]

# Fifteen minutes
MAX_TIMEOUT_SECS = 30 * 60
# GCS bucket for flutter devicelab build app artifacts.
DEVICELAB_BUCKET = 'flutter_devicelab'


def RunSteps(api):
  # Collect memory/cpu/process before task execution.
  api.os_utils.collect_os_info()
  api.os_utils.print_pub_certs()
  task_name = api.properties.get("task_name")
  if not task_name:
    raise ValueError('A task_name property is required')

  # Artifact needs pre-built before running the test.
  artifact = api.properties.get('artifact', None)
  if not artifact:
    raise ValueError('An artifact property is required')

  flutter_path = api.path.mkdtemp().join('flutter sdk')
  api.repo_util.checkout(
      'flutter',
      flutter_path,
      api.properties.get('git_url'),
      api.properties.get('git_ref'),
  )
  with api.context(cwd=flutter_path):
    commit_time = api.git(
        'git commit time',
        'log',
        '--pretty=format:%ct',
        '-n',
        '1',
        stdout=api.raw_io.output_text()
    ).stdout.rstrip()
  env, env_prefixes = api.repo_util.flutter_environment(flutter_path)
  api.logs_util.initialize_logs_collection(env)
  with api.step.nest('Dependencies'):
    api.flutter_deps.flutter_engine(env, env_prefixes)
    deps = api.properties.get('dependencies', [])
    # TODO: If deps contains dart_sdk and we are running a local engine,
    # we don't want to fetch it with cipd, so don't fetch it with required_deps
    api.flutter_deps.required_deps(env, env_prefixes, deps)

  target_tags = api.properties.get('tags', [])
  device_tags = api.test_utils.collect_benchmark_tags(
      env, env_prefixes, target_tags
  )
  benchmark_tags = api.json.dumps(device_tags)

  devicelab_path = flutter_path.join('dev', 'devicelab')
  git_branch = api.properties.get('git_branch')
  # Create tmp file to store results in
  results_path = api.path.mkdtemp(prefix='results').join('results')
  # Run test
  parent_builder = api.properties.get('parent_builder')
  runner_params = [
      '-t', task_name, '--results-file', results_path, '--luci-builder',
      parent_builder
  ]
  # Downloads artifact
  artifact_destination_dir = api.path.mkdtemp()
  download_artifact(api, artifact, artifact_destination_dir)
  # Test taskArgs
  artifact_path = artifact_destination_dir.join(artifact)
  runner_params.extend([
      '--task-args', 'test', '--task-args',
      'application-binary-path=%s' % artifact_path
  ])
  if 'LOCAL_ENGINE' in env:
    runner_params.extend(['--local-engine', env['LOCAL_ENGINE']])
  # LUCI git checkouts end up in a detached HEAD state, so branch must
  # be passed from gitiles -> test runner -> Cocoon.
  if git_branch and api.properties.get('git_url') is None:
    # git_branch is set only when the build was triggered on post-submit.
    runner_params.extend(['--git-branch', git_branch])
  test_status = ''
  with api.context(env=env, env_prefixes=env_prefixes, cwd=devicelab_path):
    api.retry.run_flutter_doctor()
    api.step('dart pub get', ['dart', 'pub', 'get'], infra_step=True)
    dep_list = {d['dependency']: d.get('version') for d in deps}
    if 'xcode' not in dep_list:
      with api.context(env=env, env_prefixes=env_prefixes):
        run_test(api, task_name, runner_params)
    else:
      api.os_utils.clean_derived_data()
      if str(api.swarming.bot_id).startswith('flutter-devicelab'):
        with api.osx_sdk('ios', devicelab=True):
          with api.context(env=env, env_prefixes=env_prefixes):
            run_test(api, task_name, runner_params)

  with api.context(env=env, env_prefixes=env_prefixes, cwd=devicelab_path):
    uploadResults(
        api, env, env_prefixes, results_path, test_status == 'flaky',
        git_branch, parent_builder, commit_time, task_name, benchmark_tags
    )
    uploadMetricsToCas(api, results_path)


def run_test(api, task_name, runner_params):
  '''Run the devicelab test.'''
  api.retry.run_flutter_doctor()
  test_runner_command = ['dart', 'bin/test_runner.dart', 'test']
  test_runner_command.extend(runner_params)
  try:
    test_status = api.test_utils.run_test(
        'run %s' % task_name,
        test_runner_command,
        timeout_secs=MAX_TIMEOUT_SECS
    )
  finally:
    debug_after_failure(api, task_name)
    if test_status == 'flaky':
      api.test_utils.flaky_step('run %s' % task_name)


def download_artifact(api, artifact, artifact_destination_dir):
  '''Download pre-build artifact.'''
  commit_sha = api.repo_util.get_env_ref()
  bucket = api.buildbucket.build.builder.bucket
  artifact_gcs_dir = 'flutter/%s/%s' % (bucket, commit_sha)
  artifact_gcs_path = '%s/%s' % (artifact_gcs_dir, artifact)
  api.gsutil.download(
      DEVICELAB_BUCKET,
      artifact_gcs_path,
      artifact_destination_dir,
      args=['-r'],
      name="download artifact"
  )


def debug_after_failure(api, task_name):
  """Upload logs and collect OS debug info."""
  api.logs_util.upload_logs(task_name)
  # This is to clean up leaked processes.
  api.os_utils.kill_processes()
  # Collect memory/cpu/process after task execution.
  api.os_utils.collect_os_info()


def shouldNotUpdate(api, git_branch):
  """Check if a post submit builder should update results to cocoon/skia perf.

  Test results will be sent to cocoon/skia perf only when test is post-submit and test is from
  supported branches.
  """
  supported_branches = ['master']
  if api.runtime.is_experimental or api.properties.get(
      'git_url') or git_branch not in supported_branches:
    return True
  else:
    return False


def uploadResults(
    api,
    env,
    env_prefixes,
    results_path,
    is_test_flaky,
    git_branch,
    builder_name,
    commit_time,
    task_name,
    benchmark_tags,
    test_status='Succeeded',
):
  """Upload DeviceLab test results to Cocoon/skia perf.

  luci-auth only gurantees a service account token life of 3 minutes. To work
  around this limitation, results uploading is separate from the the test run.

  Only post-submit tests upload results to Cocoon/skia perf.

  If `upload_metrics: true`, generated test metrics will be uploaded to skia perf
  for both prod and staging tests.

  Otherwise, test status will be updated in Cocoon for tests running in prod pool,
  and staging tests without `upload_metrics: true` will not be updated.

  Args:
    env(dict): Current environment variables.
    env_prefixes(dict):  Current environment prefixes variables.
    results_path(str): Path to test results.
    is_test_flaky(bool): Flaky flag for the test running step.
    git_branch(str): Branch the test runs against.
    builder_name(str): The builder name that is being run on.
    commit_time(str): The commit time in UNIX timestamp.
    task_name(str): The task name of the current test.
    benchmark_tags(str): Json dumped str of benchmark tags, which includes host and device info.
    test_status(str): The status of the test running step.
  """
  if shouldNotUpdate(api, git_branch):
    return
  bucket = api.buildbucket.build.builder.bucket
  runner_params = ['--test-flaky', is_test_flaky, '--builder-bucket', bucket]
  if api.properties.get('upload_metrics'):
    runner_params.extend([
        '--results-file', results_path, '--commit-time', commit_time,
        '--task-name', task_name, '--benchmark-tags', benchmark_tags
    ])
  else:
    # For builders without `upload_metrics: true`
    #  - prod ones need to update test status, to be reflected on go/flutter-build
    #  - staging ones do not need to as we are not tracking staging tests in cocoon datastore.
    if bucket == 'staging':
      return
    else:
      runner_params.extend([
          '--git-branch', git_branch, '--luci-builder', builder_name,
          '--test-status', test_status
      ])

  with api.step.nest('Upload metrics'):
    env['TOKEN_PATH'] = api.token_util.metric_center_token()
    env['GCP_PROJECT'] = 'flutter-infra'
    runner_params.extend([
        '--service-account-token-file',
        api.token_util.cocoon_token()
    ])
    upload_command = ['dart', 'bin/test_runner.dart', 'upload-metrics']
    upload_command.extend(runner_params)
    with api.context(env=env, env_prefixes=env_prefixes):
      api.step('upload results', upload_command, infra_step=True)


def uploadMetricsToCas(api, results_path):
  """Upload DeviceLab test performance metrics to CAS.

  The hash of the CAS (content-addressed storage) upload is added as an
  output property to the build.
  """
  if not api.properties.get('upload_metrics_to_cas'):
    return
  cas_hash = api.cas.archive(
      'Upload metrics to CAS', api.path.dirname(results_path), results_path
  )
  api.step.active_result.presentation.properties['results_cas_hash'] = cas_hash


def GenTests(api):
  checkout_path = api.path['cleanup'].join('tmp_tmp_1', 'flutter sdk')
  yield api.test(
      "no-task-name",
      api.expect_exception('ValueError'),
  )
  yield api.test(
      "no-artifact-name",
      api.properties(
          buildername='Linux abc', task_name='abc', git_ref='refs/pull/1/head'
      ),
      api.expect_exception('ValueError'),
  )
  yield api.test(
      "artifact-exists",
      api.properties(
          buildername='Linux abc',
          task_name='abc',
          git_branch='master',
          artifact='def',
          git_ref='refs/pull/1/head',
          parent_builder='ghi',
      ),
      api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
  )
  yield api.test(
      "basic",
      api.properties(
          buildername='Linux abc',
          task_name='abc',
          git_branch='master',
          artifact='def',
          upload_metrics=True,
          upload_metrics_to_cas=True,
          parent_builder='ghi',
      ),
      api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
      api.step_data(
          'run abc',
          stdout=api.raw_io.output_text('#flaky\nthis is a flaky\nflaky: true'),
          retcode=0
      ),
      api.buildbucket.ci_build(
          project='test',
          git_repo='git.example.com/test/repo',
      ),
  )
  yield api.test(
      "experimental",
      api.properties(
          buildername='Linux abc',
          task_name='abc',
          git_branch='master',
          artifact='def',
          parent_builder='ghi',
      ),
      api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
      api.step_data(
          'run abc',
          stdout=api.raw_io.output_text('#flaky\nthis is a flaky\nflaky: true'),
          retcode=0
      ),
      api.buildbucket.ci_build(
          project='test',
          git_repo='git.example.com/test/repo',
      ),
      api.runtime(is_experimental=True),
  )
  yield api.test(
      "no-upload-metrics-linux-staging",
      api.properties(
          buildername='Linux abc',
          task_name='abc',
          artifact='def',
          upload_metrics_to_cas=True,
          git_branch='master',
          parent_builder='ghi',
      ), api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
      api.buildbucket.ci_build(
          git_ref='refs/heads/master',
          bucket='staging',
      )
  )
  yield api.test(
      "local-engine",
      api.properties(
          buildername='Linux abc',
          task_name='abc',
          local_engine_cas_hash='isolatehashlocalengine/22',
          local_engine='host-release',
          git_branch='master',
          artifact='def',
          parent_builder='ghi',
      ), api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
      api.buildbucket.ci_build(
          project='test',
          git_repo='git.example.com/test/repo',
          git_ref='refs/heads/master',
      )
  )
  yield api.test(
      "mac",
      api.properties(
          buildername='Mac_ios abc',
          task_name='abc',
          tags=['ios'],
          dependencies=[{'dependency': 'xcode'}],
          git_branch='master',
          **{'$flutter/osx_sdk': {'sdk_version': 'deadbeef',}},
          artifact='def',
          parent_builder='ghi'
      ), api.repo_util.flutter_environment_data(checkout_dir=checkout_path),
      api.platform.name('mac'),
      api.buildbucket.ci_build(git_ref='refs/heads/master',),
      api.step_data(
          'run abc',
          stdout=api.raw_io.output_text('#flaky\nthis is a flaky\nflaky: true'),
          retcode=0
      ), api.swarming.properties(bot_id='flutter-devicelab-mac-1'),
      api.step_data(
          'Find device type',
          stdout=api.raw_io.output_text('iPhone8,1'),
      )
  )
