# 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 PB.recipes.flutter.engine.engine import InputProperties
from PB.recipes.flutter.engine.engine import EnvProperties

DEPS = [
    'depot_tools/depot_tools',
    'flutter/build_util',
    'flutter/os_utils',
    'flutter/repo_util',
    'flutter/token_util',
    'recipe_engine/context',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]
PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties


def RunSteps(api, properties, env_properties):
  # Collect memory/cpu/process after task execution.
  api.os_utils.collect_os_info()

  checkout_path = api.path['cache'].join('builder', 'src')
  cache_root = api.path['cache'].join('builder')
  dart_bin = checkout_path.join(
      'third_party', 'dart', 'tools', 'sdks', 'dart-sdk', 'bin'
  )
  android_home = checkout_path.join('third_party', 'android_tools', 'sdk')
  env = {
      'ANDROID_HOME': str(android_home),
      'FLUTTER_PREBUILT_DART_SDK': 'True',
  }
  env_prefixes = {'PATH': [dart_bin]}
  api.repo_util.engine_checkout(cache_root, env, env_prefixes)
  env['ENGINE_PATH'] = cache_root
  with api.depot_tools.on_path(), api.context(env=env,
                                              env_prefixes=env_prefixes):
    api.build_util.run_gn(['--runtime-mode', 'release', '--prebuilt-dart-sdk'],
                          checkout_path)
    api.build_util.build('host_release', checkout_path, [])

  host_release_path = checkout_path.join('out', 'host_release')
  script_path = checkout_path.join(
      'flutter', 'testing', 'benchmark', 'generate_metrics.sh'
  )
  with api.context(env=env, env_prefixes=env_prefixes,
                   cwd=host_release_path), api.step.defer_results():
    api.step('Generate metrics', ['bash', script_path])
    # 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()

  benchmark_path = checkout_path.join('flutter', 'testing', 'benchmark')
  script_path = checkout_path.join(
      'flutter', 'testing', 'benchmark', 'upload_metrics.sh'
  )
  with api.token_util.metric_center_token(env, env_prefixes):
    with api.context(env=env, env_prefixes=env_prefixes, cwd=benchmark_path):
      if properties.upload_metrics:
        api.step('Upload metrics', ['bash', script_path])
      else:
        api.step('Upload metrics', ['bash', script_path, '--no-upload'])


def GenTests(api):
  for upload_metrics in [True, False]:
    test_name = 'basic_upload_metrics_%s' % upload_metrics
    yield api.test(
        test_name,
        api.properties(
            InputProperties(
                goma_jobs='200',
                no_lto=True,
                upload_metrics=upload_metrics,
            )
        )
    )
