"""Utility script to verify key authenticated routes respond without errors."""
from __future__ import annotations

import json
import os
import sys
import urllib.parse
from http.client import HTTPConnection
from http.cookies import SimpleCookie
from typing import Dict, List, Tuple

HOST = "127.0.0.1"
PORT = 8000

cookies: Dict[str, str] = {}


def _update_cookies(headers: List[Tuple[str, str]]) -> None:
    for name, value in headers:
        if name.lower() != "set-cookie":
            continue
        cookie = SimpleCookie()
        cookie.load(value)
        for key, morsel in cookie.items():
            cookies[key] = morsel.value


def _cookie_header() -> str | None:
    if not cookies:
        return None
    return "; ".join(f"{key}={value}" for key, value in cookies.items())


def request(method: str, path: str, *, body: bytes | None = None, headers: Dict[str, str] | None = None) -> Tuple[int, Dict[str, str], bytes]:
    conn = HTTPConnection(HOST, PORT, timeout=10)
    prepared_headers = {"User-Agent": "route-checker"}
    if headers:
        prepared_headers.update(headers)
    cookie_header = _cookie_header()
    if cookie_header:
        prepared_headers["Cookie"] = cookie_header

    conn.request(method, path, body=body, headers=prepared_headers)
    resp = conn.getresponse()
    payload = resp.read()
    status = resp.status
    reason = resp.reason
    response_headers = {name: value for name, value in resp.getheaders()}
    _update_cookies(list(resp.getheaders()))
    conn.close()
    print(f"{method} {path} -> {status} {reason}")
    return status, response_headers, payload


def main() -> int:
    status, _, _ = request("GET", "/login")
    if status != 200:
        print("Unexpected status for GET /login", file=sys.stderr)
        return 1

    admin_username = os.getenv("CALMINER_SEED_ADMIN_USERNAME", "admin")
    admin_password = os.getenv("CALMINER_SEED_ADMIN_PASSWORD", "M11ffpgm.")
    login_payload = urllib.parse.urlencode(
        {"username": admin_username, "password": admin_password}
    ).encode()
    status, headers, _ = request(
        "POST",
        "/login",
        body=login_payload,
        headers={"Content-Type": "application/x-www-form-urlencoded"},
    )
    if status not in {200, 303}:
        print("Login failed", file=sys.stderr)
        return 1

    location = headers.get("Location", "/")
    redirect_path = urllib.parse.urlsplit(location).path or "/"
    request("GET", redirect_path)

    request("GET", "/")
    request("GET", "/projects/ui")

    status, headers, body = request(
        "GET",
        "/projects",
        headers={"Accept": "application/json"},
    )
    projects: List[dict] = []
    if headers.get("Content-Type", "").startswith("application/json"):
        projects = json.loads(body.decode())

    if projects:
        project_id = projects[0]["id"]
        request("GET", f"/projects/{project_id}/view")
        status, headers, body = request(
            "GET",
            f"/projects/{project_id}/scenarios",
            headers={"Accept": "application/json"},
        )
        scenarios: List[dict] = []
        if headers.get("Content-Type", "").startswith("application/json"):
            scenarios = json.loads(body.decode())
        if scenarios:
            scenario_id = scenarios[0]["id"]
            request("GET", f"/scenarios/{scenario_id}/view")

    print("Cookies:", cookies)
    return 0


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