# 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 firebase lab tests.
# This recipe uses the standar flutter dependencies model and a single property
# task_name to identify the test to run.

from contextlib import contextmanager
import re

PYTHON_VERSION_COMPATIBILITY = 'PY3'

DEPS = [
    'flutter/flutter_deps',
    'flutter/repo_util',
    'flutter/retry',
    'fuchsia/gcloud',
    'fuchsia/gsutil',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
    'recipe_engine/swarming',
]


def RunSteps(api):
  checkout_path = api.path['start_dir'].join('flutter')
  gcs_bucket = 'flutter_firebase_testlab'
  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)
  task_name = api.properties.get('task_name')

  physical_devices = [
      # Physical devices - use only highly available devices to avoid timeouts.
      # Pixel 3
      '--device',
      'model=blueline,version=28',
      # Pixel 5
      '--device',
      'model=redfin,version=30',
      # Moto Z XT1650
      '--device',
      'model=griffin,version=24',
  ]

  virtual_devices = [
      # Virtual devices for API level coverage.
      '--device',
      'model=Nexus5,version=19',
      # SDK 20 not available virtually or physically.
      '--device',
      'model=Nexus5,version=21',
      '--device',
      'model=Nexus5,version=22',
      '--device',
      'model=Nexus5,version=23',
      # SDK 24 is run on a physical griffin/Moto Z above.
      '--device',
      'model=Nexus6P,version=25',
      '--device',
      'model=Nexus6P,version=26',
      '--device',
      'model=Nexus6P,version=27',
      # SDK 28 is run on a physical blueline/Pixel 3 above.
      '--device',
      'model=NexusLowRes,version=29',
      # SDK 30 is run on a physical redfin/Pixel 5 above.
  ]

  test_configurations = (
      (
          'Build appbundle', [
              'flutter', 'build', 'appbundle', '--target-platform',
              'android-arm,android-arm64'
          ], 'build/app/outputs/bundle/release/app-release.aab',
          physical_devices
      ),
      (
          'Build apk', [
              'flutter', 'build', 'apk', '--debug', '--target-platform',
              'android-x86'
          ], 'build/app/outputs/flutter-apk/app-debug.apk', virtual_devices
      ),
  )

  with api.context(env=env, env_prefixes=env_prefixes, cwd=checkout_path):
    api.step('flutter doctor', ['flutter', 'doctor', '-v'])
    api.step(
        'download dependencies', ['flutter', 'update-packages'],
        infra_step=True,
    )

  test_path = checkout_path.join('dev', 'integration_tests', task_name)
  with api.step.nest('test_execution') as presentation:
    with api.context(env=env, env_prefixes=env_prefixes, cwd=test_path):
      task_id = api.swarming.task_id
      api.gcloud(
          '--quiet',
          'config',
          'set',
          'project',
          'flutter-infra',
          infra_step=True,
      )
      for step_name, build_command, binary, devices in test_configurations:
        api.step(step_name, build_command)
        firebase_cmd = [
            'firebase', 'test', 'android', 'run', '--type', 'robo', '--app',
            binary, '--timeout', '2m',
            '--results-bucket=gs://%s' % gcs_bucket,
            '--results-dir=%s/%s' % (task_name, task_id)
        ] + devices

        # See https://firebase.google.com/docs/test-lab/android/command-line#script_exit_codes
        # If the firebase command fails with 1, it's likely an HTTP issue that
        # will resolve on a retry. If it fails on 15 or 20, it's explicitly
        # an infra failure on the FTL side, so we should just retry.
        def run_firebase():
          return api.gcloud(*firebase_cmd)

        api.retry.wrap(run_firebase, max_attempts=3, retriable_ret=(1, 15, 20))

      logcat_path = '%s/%s/*/logcat' % (task_name, task_id)
      tmp_logcat = api.path['cleanup'].join('logcat')
      api.gsutil.download(gcs_bucket, logcat_path, api.path['cleanup'])
      content = api.file.read_text('read', tmp_logcat)
      presentation.logs['logcat'] = content
      api.step('analyze_logcat', ['grep', 'E/flutter', tmp_logcat], ok_ret=(1,))


def GenTests(api):
  yield api.test(
      'basic', api.repo_util.flutter_environment_data(),
      api.properties(task_name='the_task')
  )

  yield api.test('failure 15',
                 api.repo_util.flutter_environment_data()) + api.step_data(
                     'test_execution.gcloud firebase', retcode=15
                 )

  yield api.test('failure 10',
                 api.repo_util.flutter_environment_data()) + api.step_data(
                     'test_execution.gcloud firebase', retcode=10
                 )
