#!/usr/bin/env python3

import argparse
import subprocess
import sys
from typing import List
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent / "test-runner"))

from wasi_test_runner.harness import run_tests
from wasi_test_runner import runtime_adapter

parser = argparse.ArgumentParser(
    description="WASI test runner"
)

parser.add_argument(
    "-f",
    "--exclude-filter",
    action="append",
    default=[],
    help="Path to JSON file indicating tests to exclude.",
)
parser.add_argument(
    "-r", "--runtime-adapter", help="Path to a runtime adapter."
)
parser.add_argument(
    "--json-output-location",
    help="JSON test result destination. If not specified, JSON output won't be generated.",
)
parser.add_argument(
    "--disable-colors",
    action="store_true",
    default=False,
    help="Disables color for console output reporter.",
)
parser.add_argument(
    "--verbose",
    action="store_true",
    default=False,
    help="Print more information about test results.",
)

def find_test_dirs():
    root = Path(__file__).parent / "tests"
    root = root.relative_to(Path('.').absolute(), walk_up=True)
    test_dirs = []
    for root, dirs, files in root.walk(on_error=print):
        if "manifest.json" in files:
            test_dirs.append(root)
    return test_dirs

def find_runtime_adapters(root, verbose=False):
    print(f"Detecting WASI runtime availability:")
    adapters = []
    for candidate in root.glob("*.py"):
        try:
            adapter = runtime_adapter.RuntimeAdapter(candidate)
            print(f"  {candidate.name}: {adapter.get_meta()}")
            adapters.append(adapter)
        except runtime_adapter.LegacyRuntimeAdapterError:
            print(f"  {candidate} is too old; update to new module format.")
        except runtime_adapter.UnavailableRuntimeAdapterError:
            print(f"  {candidate.name} unavailable; pass `--runtime {candidate}` to debug.")
    print("")
    if len(adapters) == 0:
        print("Error: No WASI runtimes found")
        sys.exit(1)
    return adapters

options = parser.parse_args()
test_suite = find_test_dirs()
if options.runtime_adapter:
    try:
        runtime_adapters = [
            runtime_adapter.RuntimeAdapter(options.runtime_adapter)
        ]
    except runtime_adapter.LegacyRuntimeAdapterError as e:
        print(f"Error: {e.adapter_path} is too old; update to new module format.")
        sys.exit(1)
    except runtime_adapter.UnavailableRuntimeAdapterError as e:
        print(f"Error: failed to load {e.adapter_path}: {e.error}")
        sys.exit(1)
else:
    runtime_adapters = find_runtime_adapters(Path(__file__).parent / "adapters")

sys.exit(run_tests(runtime_adapters, test_suite,
                   color=not options.disable_colors,
                   json_log_file=options.json_output_location,
                   verbose=options.verbose,
                   exclude_filters=options.exclude_filter))
