#!/usr/bin/env python3

import argparse
import collections
import enum
import subprocess
import sys

import regen
import test_
import util

EXAMPLES = """
Examples:

Regen goldens and checked in bindings based on changed files in the current
repo

    fidldev regen

Explicitly specify regen scripts:

    fidldev regen fidlc fidlgen_dart
    fidldev regen all

Check which regen commands should be run:

    fidldev regen --dry-run

Run tests based on changed files in the current repo:

    fidldev test

Explicitly specify tests:

    fidldev test fidlc hlcpp llcpp c

Interactively filter test targets:

    fidldev test --interactive

Check which tests should be run:

    fidldev test --dry-run --no-regen

Pass flags to invocations of fx test:

    fidldev test --fx-test-args="-v -o --dry"

Pass a gtest_filter to fidlc test:

    fidldev test --gtest_filter 'EnumsTests.*'

"""

VALID_TEST_TARGETS = [name for (name, _) in test_.TEST_GROUPS] + ['all']
VALID_REGEN_TARGETS = regen.REGEN_TARGETS + ['all']


def test(args):
    success = True
    if args.targets:
        if not args.no_regen:
            util.print_warning(
                'explicit test targets provided, skipping regen...')
        unknown_args = set(args.targets) - set(VALID_TEST_TARGETS)
        if unknown_args:
            util.print_err(
                'Error: unknown test targets {}'.format(unknown_args))
            print('use `fidldev test --help` to print list of valid targets')
            sys.exit(1)
        tests = test_.test_explicit(args.targets)
    else:
        changed_files = util.get_changed_files()
        if not args.no_regen:
            regen.regen_changed(changed_files, args.dry_run)
            changed_files = util.get_changed_files()
        tests = test_.test_changed(changed_files)
        if args.dry_run:
            print_dryrun_warning()

    success = test_.run_tests(tests, args.dry_run,
                              args.interactive, args.fx_test_args,
                              args.gtest_filter)
    if not success:
        sys.exit(1)


def regen_cmd(args):
    if args.targets:
        unknown_args = set(args.targets) - set(VALID_REGEN_TARGETS)
        if unknown_args:
            util.print_err(
                'Error: unknown regen targets {}'.format(unknown_args))
            print('use `fidldev regen --help` to print list of valid targets')
            sys.exit(1)
        regen.regen_explicit(args.targets, args.dry_run)
    else:
        changed_files = util.get_changed_files()
        regen.regen_changed(changed_files, args.dry_run)
        if args.dry_run:
            print_dryrun_warning()


def print_dryrun_warning():
    print('NOTE: dry run is conservative and assumes that regen will '
          'always change files. If goldens do not change during an actual '
          'run, fewer tests/regen scripts may be run.')


parser = argparse.ArgumentParser(
    description="FIDL development workflow tool",
    formatter_class=argparse.RawDescriptionHelpFormatter,
    epilog=EXAMPLES)
subparsers = parser.add_subparsers()

test_parser = subparsers.add_parser("test", help="Test your FIDL changes")
test_parser.set_defaults(func=test)
test_parser.add_argument(
    'targets',
    metavar='target',
    nargs='*',
    help=
    "Manually specify targets to regen, where a target is one of {}. Omit positional arguments to test based on changed files"
    .format(VALID_TEST_TARGETS))
test_parser.add_argument(
    "--dry-run",
    "-n",
    help="Print out test commands without running",
    action="store_true",
)
test_parser.add_argument(
    "--no-regen",
    "-r",
    help="Don't regen goldens before running tests",
    action="store_true",
)
test_parser.add_argument(
    "--interactive",
    "-i",
    help="Interactively filter tests to be run",
    action="store_true",
)
test_parser.add_argument(
    "--fx-test-args",
    "-t",
    help=
    "Extra flags and arguments to pass to any invocations of fx test. The flag value is passed verbatim. By default, only '-v' is used.",
    default='-v',
)
test_parser.add_argument(
    "--gtest_filter",
    help="Pass a gtest filter to fidlc tests"
)

regen_parser = subparsers.add_parser("regen", help="Run regen commands")
regen_parser.set_defaults(func=regen_cmd)
regen_parser.add_argument(
    'targets',
    metavar='target',
    nargs='*',
    help=
    "Manually specify targets to regen, where a target is one of {}. Omit positional arguments to regen based on changed files"
    .format(VALID_REGEN_TARGETS))
regen_parser.add_argument(
    "--dry-run",
    "-n",
    help="Print out commands without running them",
    action="store_true",
)

if __name__ == '__main__':
    args = parser.parse_args()
    try:
        func = args.func
    except AttributeError:
        parser.print_help(sys.stderr)
        sys.exit(1)
    func(args)
