#!/usr/bin/env python3
from __future__ import annotations

import argparse
import datetime as dt
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from tests.harness.agent_process import AgentProcess
from tests.harness.didactyl_client import DidactylClient
from tests.harness.log_watcher import LogWatcher
from tests.harness.reporter import Reporter
from tests.harness.test_runner import TestRunner


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description="Didactyl automated test harness")
    parser.add_argument("--config", default="tests/configs/test_genesis.jsonc")
    parser.add_argument("--binary", default="./didactyl")
    parser.add_argument("--suite", action="append", help="Run only this suite (repeatable)")
    parser.add_argument("--test", action="append", help="Run only this test name (repeatable)")
    parser.add_argument("--api-port", type=int, default=8485)
    parser.add_argument("--api-bind", default="127.0.0.1")
    parser.add_argument("--timeout", type=float, default=60.0)
    parser.add_argument("--debug-level", type=int, default=5)
    parser.add_argument("--output-dir", default=None)
    parser.add_argument("--verbose", action="store_true")
    parser.add_argument("--no-restart", action="store_true")
    return parser.parse_args()


def main() -> int:
    args = parse_args()

    run_ts = dt.datetime.now(dt.timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    output_dir = args.output_dir or f"tests/results/{run_ts}"
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    binary = Path(args.binary)
    if not binary.exists():
        print(f"didactyl binary not found: {binary}")
        return 2

    config = Path(args.config)
    if not config.exists():
        print(f"config not found: {config}")
        return 2

    log_file = str(Path(output_dir) / "agent_debug.log")
    base_url = f"https://{args.api_bind}:{args.api_port}"

    agent = AgentProcess(
        binary_path=str(binary),
        config_path=str(config),
        api_port=args.api_port,
        api_bind=args.api_bind,
        debug_level=args.debug_level,
        log_file=log_file,
        base_url=base_url,
    )
    client = DidactylClient(base_url=base_url, timeout=args.timeout, verify_tls=False)
    log = LogWatcher(log_file)

    log.start()
    started = agent.start(timeout=30)
    if not started:
        print("Failed to start Didactyl agent")
        log.stop()
        return 1

    try:
        runner = TestRunner(agent=agent, client=client, log=log, args=args)
        tests = runner.discover_suites("tests.suites")
        if not tests:
            print("No tests discovered")
            return 3

        results = runner.run_all(tests)

        run_meta = {
            "run_timestamp": dt.datetime.now(dt.timezone.utc).isoformat(),
            "base_url": base_url,
            "config": str(config),
            "binary": str(binary),
            "test_count": len(results),
        }
        reporter = Reporter(results=results, run_meta=run_meta, output_dir=output_dir)
        reporter.print_summary()
        reporter.print_details()
        json_path = reporter.write_json("results.json")
        txt_path = reporter.write_text("results.txt")
        print(f"\nWrote: {json_path}")
        print(f"Wrote: {txt_path}")

        bad = [r for r in results if r.status in {"fail", "error", "timeout"}]
        return 1 if bad else 0
    finally:
        agent.stop(timeout=10)
        log.stop()


if __name__ == "__main__":
    raise SystemExit(main())
