import json
import os
import socket
import ssl
import subprocess
import time
import urllib.request


def inspect_system():
    log_entries = []

    def log(msg):
        print(msg)
        log_entries.append(msg)

    log("=" * 60)
    log(
        f"DSCons System Diagnostics & Live Verification - {time.strftime('%Y-%m-%d %H:%M:%S')}"
    )
    log("=" * 60)

    # 1. Inspect processes
    log(
        "\n[1] Checking running processes (Python, Cloudflared, Postgres, SSH, Tailscale)..."
    )
    try:
        ps_cmd = 'Get-CimInstance Win32_Process | Where-Object { $_.Name -match "python|cloudflared|uvicorn|postgres|sshd|tailscale" } | Select-Object ProcessId, Name, CommandLine | ConvertTo-Json'
        proc = subprocess.run(
            ["powershell", "-NoProfile", "-Command", ps_cmd],
            capture_output=True,
            text=True,
        )
        if proc.stdout.strip():
            processes = json.loads(proc.stdout)
            if isinstance(processes, dict):
                processes = [processes]
            for p in processes:
                log(f"  PID {p.get('ProcessId')}: {p.get('Name')}")
                log(f"    Command: {p.get('CommandLine')}")
        else:
            log("  No matching processes returned.")
    except Exception as e:
        log(f"  Error inspecting processes: {e}")

    # 2. Check ports
    log("\n[2] Checking critical network ports...")
    ports = [
        ("127.0.0.1", 8000, "FastAPI / Uvicorn Backend"),
        ("127.0.0.1", 1234, "LM Studio (Local LLM API)"),
        ("127.0.0.1", 5432, "PostgreSQL Database"),
        ("127.0.0.1", 22, "OpenSSH Server"),
        ("127.0.0.1", 6333, "Qdrant Vector Engine"),
    ]
    for host, port, name in ports:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(2)
        try:
            s.connect((host, port))
            s.close()
            log(f"  [OK] {name} ({host}:{port}) is OPEN.")
        except Exception:
            log(f"  [WARN] {name} ({host}:{port}) is CLOSED / NOT LISTENING.")

    # 3. Check Cloudflare Tunnel
    log("\n[3] Checking Cloudflare Tunnel status...")
    try:
        cf_check = subprocess.run(
            ["cloudflared", "tunnel", "info", "dscons-erp"],
            capture_output=True,
            text=True,
        )
        log("  Tunnel Info Output:")
        for l in cf_check.stdout.splitlines()[:10]:
            log(f"    {l}")
        if cf_check.stderr:
            for l in cf_check.stderr.splitlines()[:5]:
                log(f"    [ERR] {l}")
    except Exception as e:
        log(f"  Error querying cloudflared: {e}")

    # 4. Check HTTP endpoints
    log("\n[4] Testing HTTP Endpoints (Local & Public Domains)...")
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    endpoints = [
        ("Local Health Check", "http://127.0.0.1:8000/health"),
        ("Local API Docs", "http://127.0.0.1:8000/docs"),
        ("Public Landing Health", "https://dinhsonconstruction.com/health"),
        ("Public Landing Page", "https://dinhsonconstruction.com/"),
        ("Public Login Page", "https://dinhsonconstruction.com/login"),
        ("Public Dashboard", "https://dinhsonconstruction.com/dashboard"),
        ("Public Projects View", "https://dinhsonconstruction.com/dashboard/projects"),
        ("Public Invoices View", "https://dinhsonconstruction.com/dashboard/invoices"),
        (
            "Public Employees View",
            "https://dinhsonconstruction.com/dashboard/employees",
        ),
        (
            "Public Readiness View",
            "https://dinhsonconstruction.com/dashboard/readiness",
        ),
        ("Public Subdomain ERP", "https://erp.dinhsonconstruction.com/"),
    ]

    results = {}
    for name, url in endpoints:
        try:
            req = urllib.request.Request(
                url, headers={"User-Agent": "DSCons-Diagnostic-Bot/1.0"}
            )
            start_t = time.time()
            with urllib.request.urlopen(
                req, timeout=10, context=ctx if url.startswith("https") else None
            ) as resp:
                elapsed = round((time.time() - start_t) * 1000, 2)
                body = resp.read()
                results[name] = {
                    "status": resp.status,
                    "size": len(body),
                    "time_ms": elapsed,
                    "error": None,
                }
                log(
                    f"  [SUCCESS] {name} ({url}) -> Status: {resp.status}, Size: {len(body):,} bytes, Latency: {elapsed}ms"
                )
        except Exception as e:
            results[name] = {
                "status": None,
                "size": 0,
                "time_ms": None,
                "error": str(e),
            }
            log(f"  [FAILURE] {name} ({url}) -> Error: {e}")

    # 5. Summary & Logging
    log("\n" + "=" * 60)
    log("Diagnostic Summary:")
    failures = [k for k, v in results.items() if v.get("error")]
    if failures:
        log(f"  ATTENTION: {len(failures)} endpoint(s) failed: {', '.join(failures)}")
    else:
        log("  ALL ENDPOINTS AND SERVICES ARE OPERATIONAL AND HEALTHY (100% UP).")
    log("=" * 60)

    # Save log
    log_file = "system_scan_and_website_diagnostic.log"
    with open(log_file, "w", encoding="utf-8") as f:
        f.write("\n".join(log_entries))
    log(f"\nAudit log saved to {os.path.abspath(log_file)}")


if __name__ == "__main__":
    inspect_system()
