import argparse
import sys
from pathlib import Path

from .api import serve
from .config import load_config
from .db.connection import connect
from .db.migrations import apply_migrations
from .reports import render_json, render_markdown
from .watcher import Watcher


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="watcher")
    parser.add_argument("--config", type=Path, default=Path("config.yaml"))
    sub = parser.add_subparsers(dest="command", required=True)
    sub.add_parser("migrate")
    sub.add_parser("validate-config")
    sub.add_parser("scan")
    report = sub.add_parser("report")
    report.add_argument("--format", choices=("json", "markdown"), default="json")
    sub.add_parser("serve")
    retention = sub.add_parser("retention")
    retention.add_argument("--apply", action="store_true", help="delete records outside configured retention windows")
    args = parser.parse_args(argv)
    if args.command == "validate-config":
        config = load_config(args.config)
        print(f"valid: {args.config} ({len(config.collectors)} collectors)")
        return 0
    if args.command == "migrate":
        config = load_config(args.config)
        connection = connect(config.watcher.database_path)
        version = apply_migrations(connection)
        connection.close()
        print(f"schema version: {version}")
        return 0
    config = load_config(args.config)
    watcher = Watcher(config, args.config.parent)
    try:
        if args.command == "scan":
            result = watcher.run_once()
            print(f"cycle: {result.observations_created} observations, {result.collectors_failed} collector failures")
        elif args.command == "report":
            print(render_markdown(watcher) if args.format == "markdown" else render_json(watcher))
        elif args.command == "serve":
            serve(watcher, config.watcher.api_host, config.watcher.api_port)
        elif args.command == "retention":
            values = config.watcher.retention
            counts = watcher.repository.retention({"job_observations": values.job_observations_days,
                                                   "job_runs": values.job_runs_days,
                                                   "status_events": values.status_events_days,
                                                   "collector_runs": values.collector_runs_days,
                                                   "watcher_events": values.watcher_events_days},
                                                  dry_run=not args.apply or not values.enabled)
            mode = "dry-run" if not args.apply or not values.enabled else "applied"
            print(f"retention {mode}: {counts}")
    finally:
        watcher.close()
    return 0


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