#!/usr/bin/env python3
import argparse
import importlib
import json
import os
import shutil
import sqlite3
import subprocess
import sys
from pathlib import Path


REQUIRED_MODULES = (
    ("flask", "Flask"),
    ("requests", "Requests"),
    ("PIL", "Pillow"),
    ("folium", "Folium"),
    ("FlightRadarAPI", "FlightRadarAPI"),
    ("rgbmatrix", "RGB matrix binding"),
)


def check(label, ok, detail=""):
    status = "PASS" if ok else "FAIL"
    suffix = f" - {detail}" if detail else ""
    print(f"[{status}] {label}{suffix}")
    return bool(ok)


def command_ok(command):
    try:
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=15,
        )
        return result.returncode == 0, (result.stdout or result.stderr).strip()
    except Exception as exc:
        return False, str(exc)


def sqlite_ok(path, table):
    try:
        path.parent.mkdir(parents=True, exist_ok=True)
        with sqlite3.connect(path, timeout=10) as connection:
            row = connection.execute(
                "SELECT name FROM sqlite_master WHERE type='table' AND name=?",
                (table,),
            ).fetchone()
            if not row:
                return False, f"missing table {table}"
            connection.execute(f"SELECT COUNT(*) FROM {table}").fetchone()
            result = connection.execute("PRAGMA quick_check").fetchone()
            return result and result[0] == "ok", result[0] if result else "no result"
    except Exception as exc:
        return False, str(exc)


def main():
    parser = argparse.ArgumentParser(description="Validate a Plane Tracker installation")
    parser.add_argument(
        "--install-dir",
        default=str(Path(__file__).resolve().parents[1]),
    )
    parser.add_argument("--skip-service", action="store_true")
    args = parser.parse_args()

    root = Path(args.install_dir).resolve()
    failures = 0
    failures += not check("Application directory", root.is_dir(), str(root))
    failures += not check("Main application", (root / "its-a-plane.py").is_file())
    failures += not check("Web application", (root / "web" / "app.py").is_file())
    failures += not check("NetworkManager command", bool(shutil.which("nmcli")))

    for module_name, label in REQUIRED_MODULES:
        try:
            importlib.import_module(module_name)
            ok, detail = True, ""
        except Exception as exc:
            ok, detail = False, str(exc)
        failures += not check(label, ok, detail)

    sys.path.insert(0, str(root))
    os.environ["PLANE_TRACKER_NO_MATRIX"] = "1"
    try:
        main_module = root / "its-a-plane.py"
        namespace = {"__file__": str(main_module), "__name__": "factory_check"}
        source = main_module.read_text(encoding="utf-8-sig")
        prefix = source.split('if __name__ == "__main__":', 1)[0]
        exec(compile(prefix, str(main_module), "exec"), namespace)
        namespace["_ensure_config"]()
        config_data = json.loads(
            (root / "config" / "config.json").read_text(encoding="utf-8-sig")
        )
        failures += not check("Default configuration", isinstance(config_data, dict))
    except Exception as exc:
        failures += not check("Default configuration", False, str(exc))

    try:
        from utilities import flight_history, route_db

        route_db.stats()
        flight_history.ensure_ready()
        route_ok, route_detail = sqlite_ok(Path(route_db.DB_PATH), "route_cache")
        history_ok, history_detail = sqlite_ok(
            Path(flight_history.DB_PATH),
            "flight_events",
        )
        failures += not check("Route database", route_ok, route_detail)
        failures += not check("Flight-history database", history_ok, history_detail)
    except Exception as exc:
        failures += not check("Database initialization", False, str(exc))

    if not args.skip_service:
        service_ok, service_detail = command_ok(
            ["systemctl", "is-enabled", "its-a-plane.service"]
        )
        failures += not check("System service enabled", service_ok, service_detail)

    print()
    if failures:
        print(f"Factory validation failed: {failures} check(s) need attention.")
        return 1
    print("Factory validation passed.")
    return 0


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