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

PYTHON_VERSION_COMPATIBILITY = 'PY3'

DEPS = [
    'depot_tools/depot_tools',
    'flutter/android_virtual_device',
    'flutter/bucket_util',
    'flutter/flutter_deps',
    'flutter/os_utils',
    'flutter/repo_util',
    'fuchsia/goma',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    '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 RunAndroidUnitTests(api, env, env_prefixes):
  """Runs the unit tests for the Android embedder on a x64 Android Emulator."""
  engine_checkout = GetCheckoutPath(api)
  test_dir = engine_checkout.join('flutter', 'testing')
  exe_path = engine_checkout.join('out', 'android_debug_x64', 'flutter_shell_native_unittests')
  with api.context(cwd=test_dir, env=env, env_prefixes=env_prefixes):
    result = api.step(
        'Android Unit Tests',
        ['./run_tests.py', '--android-variant', 'android_debug_x64', '--type', 'android', '--adb-path', env['ADB_PATH']]
    )

def RunAndroidScenarioTests(api, env, env_prefixes):
  """Runs the scenario test app on a x64 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)

  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]}), api.step.defer_results():

    result = api.step(
        'Scenario App Integration Tests',
        ['./run_android_tests.sh', 'android_debug_x64'],
        ok_ret='all'
    )
    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.flutter_deps.required_deps(
      env, env_prefixes, api.properties.get('dependencies', [])
  )
  api.android_virtual_device.start(env, env_prefixes)
  api.android_virtual_device.setup(env, env_prefixes)

  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=x64', '--no-lto')
    Build(api, 'android_debug_x64', 'scenario_app', 'flutter_shell_native_unittests')

    RunAndroidUnitTests(api, env, env_prefixes)
    RunAndroidScenarioTests(api, env, env_prefixes)
    api.step('Kill emulator', ['kill', '-9', env['EMULATOR_PID']])

  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'
  )
  avd_api_version = '31'
  for upload_packages in (True, False):
    yield api.test(
        'without_failure_upload_%d' % upload_packages,
        api.properties(
            dependencies=[
              {'dependency':'android_virtual_device', 'version':'31'},
            ]
        ),
        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 avd.Start Android emulator (API level %s)' % avd_api_version,
            stdout=api.raw_io.output_text(
                'android_' + avd_api_version + '_google_apis_x86|emulator-5554 started (pid: 17687)'
            )
        ),
    )
    test = api.test(
        'with_failure_upload_%d' % upload_packages,
        api.properties(
            dependencies=[
              {'dependency':'android_virtual_device', 'version':'31'},
            ]
        ),
        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 avd.Start Android emulator (API level %s)' % avd_api_version,
            stdout=api.raw_io.output_text(
                'android_' + avd_api_version + '_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
