#!/usr/bin/env python3
#
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import json
import os
import re
import sys

# The basic shell script for client test run in Skylab. The arguments listed
# here will be fed by autotest at the run time.
#
# * test-launcher-summary-output: the path for the json result. It will be
#     assigned by autotest, who will upload it to GCS upon test completion.
# * test-launcher-shard-index: the index for this test run.
# * test-launcher-total-shards: the total test shards.
# * test_args: arbitrary runtime arguments configured in test_suites.pyl,
#     attached after '--'.
BASIC_SHELL_SCRIPT = """
#!/bin/sh

while [[ $# -gt 0 ]]; do
    case "$1" in
        --test-launcher-summary-output)
            summary_output=$2
            shift 2
            ;;

        --test-launcher-shard-index)
            shard_index=$2
            shift 2
            ;;

        --test-launcher-total-shards)
            total_shards=$2
            shift 2
            ;;

        --)
            test_args=$2
            break
            ;;

        *)
            break
            ;;
    esac
done

if [ ! -d $(dirname $summary_output) ] ; then
    mkdir -p $(dirname $summary_output)
fi

cd `dirname $0` && cd ..
"""


def build_test_script(args):
  # Build the shell script that will be used on the device to invoke the test.
  # Stored here as a list of lines.
  device_test_script_contents = BASIC_SHELL_SCRIPT.split('\n')

  test_invocation = ('LD_LIBRARY_PATH=./ ./%s '
                     ' --test-launcher-summary-output=$summary_output'
                     ' --test-launcher-shard-index=$shard_index'
                     ' --test-launcher-total-shards=$total_shards'
                     ' $test_args' % args.test_exe)

  device_test_script_contents.append(test_invocation)
  with open(args.output, 'w') as w:
    w.write('\n'.join(device_test_script_contents))
  os.chmod(args.output, 0o755)


def build_filter_file(args):
  # TODO(b/227381644): This expression is hard to follow and  should be
  # simplified. This would require a change on the cros infra side as well
  tast_expr_dict = {}
  default_disabled_tests = []
  if args.disabled_tests is not None:
    default_disabled_tests = [
        '!"name:{0}"'.format(test) for test in args.disabled_tests
    ]

  default_enabled_test_term = ''
  if args.enabled_tests is not None:
    default_enabled_test_term = (' || ').join(
        ['"name:{0}"'.format(test) for test in args.enabled_tests])

  # Generate the default expression to be used when there is no known key
  tast_expr = args.tast_expr if args.tast_expr else ""

  if default_disabled_tests:
    default_disabled_term = " && ".join(default_disabled_tests)
    tast_expr = "{0} && {1}".format(tast_expr, default_disabled_term) if \
      tast_expr else default_disabled_term

  if default_enabled_test_term:
    tast_expr = "{0} && ({1})".format(
        tast_expr,
        default_enabled_test_term) if tast_expr else default_enabled_test_term

  tast_expr_dict['default'] = "({0})".format(tast_expr)

  # Generate an expression for each collection in the gni file
  if args.tast_control is not None:
    with open(args.tast_control, 'r') as tast_control_file:
      gni = tast_control_file.read()
      filter_lists = re.findall(r'(.*) = \[([^\]]*)\]', gni)
      for filter_list in filter_lists:
        tast_expr = args.tast_expr if args.tast_expr else ""

        milestone_disabled_tests = {
            '!"name:{0}"'.format(test)
            for test in re.findall(r'"([^"]+)"', filter_list[1])
        }

        milestone_disabled_tests.update(default_disabled_tests)

        if milestone_disabled_tests:
          tast_expr = "{0} && {1}".format(
              tast_expr, " && ".join(milestone_disabled_tests)
          ) if tast_expr else " && ".join(milestone_disabled_tests)

        if default_enabled_test_term:
          tast_expr = "{0} && ({1})".format(
              tast_expr, default_enabled_test_term
          ) if tast_expr else default_enabled_test_term

        if tast_expr:
          tast_expr_dict[filter_list[0]] = "({0})".format(tast_expr)

  if len(tast_expr_dict) > 0:
    with open(args.output, "w") as file:
      json.dump(tast_expr_dict, file, indent=2)
    os.chmod(args.output, 0o644)


def main():
  parser = argparse.ArgumentParser()
  subparsers = parser.add_subparsers(dest='command')

  script_gen_parser = subparsers.add_parser('generate-runner')
  script_gen_parser.add_argument(
      '--test-exe',
      type=str,
      required=True,
      help='Path to test executable to run inside the device.')
  script_gen_parser.add_argument('--verbose', '-v', action='store_true')
  script_gen_parser.add_argument(
      '--output',
      required=True,
      type=str,
      help='Path to create the runner script.')
  script_gen_parser.set_defaults(func=build_test_script)

  filter_gen_parser = subparsers.add_parser('generate-filter')
  filter_gen_parser.add_argument(
      '--tast-expr',
      type=str,
      required=False,
      help='Tast expression to determine tests to run. This creates the '
      'initial set of tests that can be further filtered.')
  filter_gen_parser.add_argument(
      '--enabled-tests',
      type=str,
      required=False,
      action='append',
      help='Name of tests to allow to test (unnamed tests will not run).')
  filter_gen_parser.add_argument(
      '--disabled-tests',
      type=str,
      required=False,
      action='append',
      help='Names of tests to disable from running')
  filter_gen_parser.add_argument(
      '--tast-control',
      type=str,
      required=False,
      help='Filename for the tast_control file containing version skew '
      'test filters to generate.')
  filter_gen_parser.add_argument(
      '--output',
      required=True,
      type=str,
      help='Path to create the plain text filter file.')
  filter_gen_parser.set_defaults(func=build_filter_file)

  args = parser.parse_args()

  if (args.command == "generate-filter" and args.disabled_tests is None and
      args.enabled_tests is None and args.tast_expr is None):
    parser.error(
        '--disabled-tests, --enabled-tests, or --tast-expr must be provided '
        'to generate-filter')

  args.func(args)

  return 0


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