#!/usr/bin/env python3
#
# Copyright 2013 The Flutter 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 argparse
import glob
import re
import os
import subprocess
import sys

if 'STORAGE_BUCKET' not in os.environ:
  print('The GCP storage bucket must be provided as an environment variable.')
  sys.exit(1)
BUCKET = os.environ['STORAGE_BUCKET']

if 'GCP_PROJECT' not in os.environ:
  print('The GCP project must be provided as an environment variable.')
  sys.exit(1)
PROJECT = os.environ['GCP_PROJECT']

script_dir = os.path.dirname(os.path.realpath(__file__))
buildroot_dir = os.path.abspath(os.path.join(script_dir, '..', '..'))
out_dir = os.path.join(buildroot_dir, 'out')
error_re = re.compile(r'[EF]/flutter.+')


def run_firebase_test(apk, results_dir):
  # game-loop tests are meant for OpenGL apps.
  # This type of test will give the application a handle to a file, and
  # we'll write the timeline JSON to that file.
  # See https://firebase.google.com/docs/test-lab/android/game-loop
  # Pixel 5. As of this commit, this is a highly available device in FTL.
  process = subprocess.Popen(
      [
          'gcloud',
          '--project',
          PROJECT,
          'firebase',
          'test',
          'android',
          'run',
          '--type',
          'game-loop',
          '--app',
          apk,
          '--timeout',
          '2m',
          '--results-bucket',
          BUCKET,
          '--results-dir',
          results_dir,
          '--device',
          'model=redfin,version=30',
      ],
      stdout=subprocess.PIPE,
      stderr=subprocess.STDOUT,
      universal_newlines=True,
  )
  return process


def check_logcat(results_dir):
  logcat = subprocess.check_output([
      'gsutil', 'cat',
      '%s/%s/*/logcat' % (BUCKET, results_dir)
  ])
  if not logcat:
    sys.exit(1)

  logcat_matches = error_re.findall(logcat)
  if logcat_matches:
    print('Errors in logcat:')
    print(logcat_matches)
    sys.exit(1)


def check_timeline(results_dir):
  gsutil_du = subprocess.check_output([
      'gsutil', 'du',
      '%s/%s/*/game_loop_results/results_scenario_0.json' %
      (BUCKET, results_dir)
  ]).strip()
  if gsutil_du == '0':
    print('Failed to produce a timeline.')
    sys.exit(1)


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '--variant',
      dest='variant',
      action='store',
      default='android_profile_arm64',
      help='The engine variant to run tests for.'
  )
  parser.add_argument(
      '--build-id',
      default=os.environ.get('SWARMING_TASK_ID', 'local_test'),
      help='A unique build identifier for this test. Used to sort results in the GCS bucket.'
  )

  args = parser.parse_args()

  apks_dir = os.path.join(out_dir, args.variant, 'firebase_apks')
  apks = glob.glob('%s/*.apk' % apks_dir)

  if not apks:
    print('No APKs found at %s' % apks_dir)
    return 1

  git_revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'],
                                         cwd=script_dir).strip()

  results = []
  apk = None
  for apk in apks:
    results_dir = '%s/%s/%s' % (
        os.path.basename(apk), git_revision, args.build_id
    )
    process = run_firebase_test(apk, results_dir)
    results.append((results_dir, process))

  for results_dir, process in results:
    for line in iter(process.stdout.readline, ''):
      print(line.strip())
    return_code = process.wait()
    if return_code != 0:
      print('Firebase test failed with code: %s' % return_code)
      sys.exit(return_code)

    print('Checking logcat for %s' % results_dir)
    check_logcat(results_dir)
    # scenario_app produces a timeline, but the android image test does not.
    if 'scenario' in apk:
      print('Checking timeline for %s' % results_dir)
      check_timeline(results_dir)

  return 0


if __name__ == '__main__':
  sys.exit(main())
