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

import re

from PB.recipes.flutter.engine.engine import InputProperties
from PB.recipes.flutter.engine.engine import EnvProperties

PYTHON_VERSION_COMPATIBILITY = 'PY3'

DEPS = [
    'depot_tools/depot_tools',
    'flutter/bucket_util',
    'flutter/os_utils',
    'flutter/repo_util',
    'fuchsia/goma',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties


def GetCheckoutPath(api):
  return api.path['cache'].join('builder', 'src')


def Build(api, config, *targets):
  checkout = GetCheckoutPath(api)
  build_dir = checkout.join('out', config)
  goma_jobs = api.properties['goma_jobs']
  ninja_args = [api.depot_tools.ninja_path, '-j', goma_jobs, '-C', build_dir]
  ninja_args.extend(targets)
  with api.goma.build_with_goma():
    name = 'build %s' % ' '.join([config] + list(targets))
    api.step(name, ninja_args)


def RunGN(api, *args):
  checkout = GetCheckoutPath(api)
  gn_cmd = ['python', checkout.join('flutter/tools/gn'), '--goma']
  gn_cmd.extend(args)
  api.step('gn %s' % ' '.join(args), gn_cmd)


def RunAndroidScenarioTests(api):
  """Runs the scenario test app on a x86 Android emulator.

  See details at
  https://chromium.googlesource.com/chromium/src/+/HEAD/docs/android_emulator.md#using-your-own-emulator-image
  """
  engine_checkout = GetCheckoutPath(api)
  android_tool_dir = engine_checkout.join('tools', 'android')

  api.cipd.ensure(
      android_tool_dir,
      api.cipd.EnsureFile().add_package(
          'chromium/tools/android/avd/linux-amd64',
          'e5JfdaCjazDFh5uqhkPgVeZa9oCLVimm5_8TWAENz1gC'
      )
  )

  avd_script_path = android_tool_dir.join(
      'src', 'tools', 'android', 'avd', 'avd.py'
  )

  avd_config = android_tool_dir.join(
      'src', 'tools', 'android', 'avd', 'proto', 'generic_android30.textpb'
  )

  emulator_pid = ''
  with api.context(cwd=android_tool_dir):
    api.python(
        'Install Android emulator (API level 30)', avd_script_path,
        ['install', '--avd-config', avd_config]
    )

    output = api.python(
        'Start Android emulator (API level 30)',
        avd_script_path,
        ['start', '--no-read-only', '--avd-config', avd_config],
        stdout=api.raw_io.output_text()
    ).stdout
    m = re.match('.*pid: (\d+)\)', output)
    emulator_pid = m.group(1)
  test_dir = engine_checkout.join('flutter', 'testing')
  scenario_app_tests = test_dir.join('scenario_app')

  # Proxies `python` since vpython cannot resolve spec files outside of the jar
  # file containing the python scripts.
  gradle_home_bin_dir = scenario_app_tests.join('android', 'gradle-home', 'bin')
  with api.context(cwd=scenario_app_tests,
                   env_prefixes={'PATH': [gradle_home_bin_dir]}):

    result = api.step(
        'Scenario App Integration Tests',
        ['./run_android_tests.sh', 'android_debug_x86'],
        ok_ret='all'
    )
    api.step('Kill emulator', ['kill', '-9', emulator_pid])
    build_failures_dir = scenario_app_tests.join('build', 'reports', 'diff_failures')
    if api.path.exists(build_failures_dir):
      # Upload any diff failures.
      # If there are any, upload them to the cloud bucket.
      api.bucket_util.upload_folder(
          'Upload diff failures',
          'src/flutter/testing/scenario_app',
          'build/reports/diff_failures',
          'diff_failures.zip',
          bucket_name='flutter_logs',
      )


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

  cache_root = api.path['cache'].join('builder')
  checkout = GetCheckoutPath(api)

  api.file.rmtree('Clobber build output', checkout.join('out'))
  api.file.ensure_directory('Ensure checkout cache', cache_root)
  api.goma.ensure()

  dart_bin = checkout.join(
      'third_party', 'dart', 'tools', 'sdks', 'dart-sdk', 'bin'
  )
  android_home = checkout.join('third_party', 'android_tools', 'sdk')
  env = {
    'GOMA_DIR': api.goma.goma_dir,
    '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, clobber=properties.clobber
  )

  with api.context(cwd=cache_root, env=env,
                   env_prefixes=env_prefixes), api.depot_tools.on_path():
    RunGN(api, '--android', '--android-cpu=x86', '--no-lto')
    Build(api, 'android_debug_x86')

    RunAndroidScenarioTests(api)

  with api.step.defer_results():
    # 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 GenTests(api):
  scenario_failures = GetCheckoutPath(api).join(
      'flutter', 'testing', 'scenario_app', 'build', 'reports', 'diff_failures'
  )
  for upload_packages in (True, False):
    yield api.test(
        'without_failure_upload_%d' % upload_packages,
        api.buildbucket.ci_build(
            builder='Linux Engine',
            git_repo='https://chromium.googlesource.com/external/github.com/flutter/engine',
            project='flutter',
            revision='abcd1234',
        ),
        api.properties(
            InputProperties(
                goma_jobs='1024',
                upload_packages=upload_packages,
            ),
        ),
        api.step_data(
            'Start Android emulator (API level 30)',
            stdout=api.raw_io.output_text(
                'android_30_google_apis_x86|emulator-5554 started (pid: 17687)'
            )
        )
    )
    test = api.test(
        'with_failure_upload_%d' % upload_packages,
        api.buildbucket.ci_build(
            builder='Linux Engine',
            git_repo='https://chromium.googlesource.com/external/github.com/flutter/engine',
            project='flutter',
            revision='abcd1234',
        ),
        api.properties(
            InputProperties(
                goma_jobs='1024',
                upload_packages=upload_packages,
                clobber=False,
            ),
        ),
        # Makes the test fail.
        api.step_data('Scenario App Integration Tests', retcode=1),
        api.path.exists(scenario_failures),
        api.step_data(
            'Start Android emulator (API level 30)',
            stdout=api.raw_io.output_text(
                'android_30_google_apis_x86|emulator-5554 started (pid: 17687)'
            )
        )
    )
    if upload_packages:
      test += api.step_data(
          'Ensure flutter/abcd1234/diff_failures.zip does not already exist on cloud storage',
          retcode=1
      )
    yield test
