#!/usr/bin/env vpython3

# [VPYTHON:BEGIN]
# python_version: "3.8"
# wheel <
#   name: "infra/python/wheels/pyyaml/${platform}_${py_python}_${py_abi}"
#   version: "version:5.4.1.chromium.1"
# >
# [VPYTHON:END]

# Copyright (c) 2013, the Flutter project 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 logging
import os
import sys

from subprocess import CompletedProcess
from typing import Any, Iterable, List, Mapping, NamedTuple, Set

# The import is coming from vpython wheel and pylint cannot find it.
import yaml  # pylint: disable=import-error

# The imports are coming from fuchsia/test_scripts and pylint cannot find them
# without setting a global init-hook which is less favorable.
# But this file will be executed as part of the CI, its correctness of importing
# is guaranteed.

sys.path.insert(
    0, os.path.join(os.path.dirname(__file__), '../../tools/fuchsia/test_scripts/test/')
)

# pylint: disable=import-error, wrong-import-position
import run_test
from common import DIR_SRC_ROOT
from run_executable_test import ExecutableTestRunner
from test_runner import TestRunner

if len(sys.argv) == 2:
  VARIANT = sys.argv[1]
  sys.argv.pop()
elif len(sys.argv) == 1:
  VARIANT = 'fuchsia_debug_x64'
else:
  assert False, 'Expect only one parameter as the compile output directory.'
OUT_DIR = os.path.join(DIR_SRC_ROOT, 'out', VARIANT)


# Visible for testing
class TestCase(NamedTuple):
  package: str
  args: str = ''


class _BundledTestRunner(TestRunner):

  # private, use bundled_test_runner_of function instead.
  def __init__(self, target_id: str, package_deps: Set[str], tests: List[TestCase], logs_dir: str):
    super().__init__(OUT_DIR, [], None, target_id, list(package_deps))
    self.tests = tests
    self.logs_dir = logs_dir

  def run_test(self) -> CompletedProcess:
    returncode = 0
    for test in self.tests:
      assert test.package.endswith('.cm')
      test_runner = ExecutableTestRunner(
          OUT_DIR, test.args.split(), test.package, self._target_id, None, self.logs_dir, [], None
      )
      # pylint: disable=protected-access
      test_runner._package_deps = self._package_deps
      result = test_runner.run_test().returncode
      logging.info('Result of test %s is %s', test, result)
      if result != 0:
        returncode = result
    return CompletedProcess(args='', returncode=returncode)


# Visible for testing
def resolve_packages(tests: Iterable[Mapping[str, Any]]) -> Set[str]:
  packages = set()
  for test in tests:
    if 'package' in test:
      packages.add(test['package'])
    else:
      assert 'packages' in test, \
             'Expect either one package or a list of packages'
      packages.update(test['packages'])
  resolved_packages = set()
  for package in packages:
    if package.endswith('-0.far'):
      # Make a symbolic link to match the name of the package itself without the
      # '-0.far' suffix.
      new_package = os.path.join(OUT_DIR, package.replace('-0.far', '.far'))
      try:
        # Remove the old one if it exists, usually happen on the devbox, so
        # ignore the FileNotFoundError.
        os.remove(new_package)
      except FileNotFoundError:
        pass
      os.symlink(package, new_package)
      resolved_packages.add(new_package)
    else:
      resolved_packages.add(os.path.join(OUT_DIR, package))
  return resolved_packages


# Visible for testing
def build_test_cases(tests: Iterable[Mapping[str, Any]]) -> List[TestCase]:
  test_cases = []
  for test in [t['test_command'] for t in tests]:
    assert test.startswith('test run ')
    test = test[len('test run '):]
    if ' -- ' in test:
      package, args = test.split(' -- ', 1)
      test_cases.append(TestCase(package=package, args=args))
    else:
      test_cases.append(TestCase(package=test))
  return test_cases


def _bundled_test_runner_of(target_id: str) -> _BundledTestRunner:
  log_dir = os.environ.get('FLUTTER_LOGS_DIR', '/tmp/log')
  with open(os.path.join(os.path.dirname(__file__), 'test_suites.yaml'), 'r') as file:
    tests = yaml.safe_load(file)
  # TODO(zijiehe-google-com): Run all tests in release build,
  # https://github.com/flutter/flutter/issues/140179.
  def variant(test) -> bool:
    return 'variant' not in test or test['variant'] in VARIANT

  tests = [t for t in tests if variant(t)]
  return _BundledTestRunner(target_id, resolve_packages(tests), build_test_cases(tests), log_dir)


def _get_test_runner(runner_args: argparse.Namespace, *_) -> TestRunner:
  return _bundled_test_runner_of(runner_args.target_id)


if __name__ == '__main__':
  logging.basicConfig(level=logging.INFO)
  logging.info('Running tests in %s', OUT_DIR)
  sys.argv.append('--out-dir=' + OUT_DIR)
  if VARIANT.endswith('_arm64') or VARIANT.endswith('_arm64_tester'):
    sys.argv.append('--product=terminal.qemu-arm64')
  # The 'flutter-test-type' is a place holder and has no specific meaning; the
  # _get_test_runner is overrided.
  sys.argv.append('flutter-test-type')
  run_test._get_test_runner = _get_test_runner  # pylint: disable=protected-access
  sys.exit(run_test.main())
