#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3 python3Packages.tldextract python3Packages.requests
import csv
import sys
import requests
import tldextract
from typing import Set


def extract_root_domain(url_or_host: str) -> str | None:
    if not url_or_host:
        return None

    parts = [p.strip() for p in url_or_host.split(",")]
    web_part = next((p for p in parts if p.startswith("http")), parts[0])

    ext = tldextract.extract(web_part)
    if ext.domain and ext.suffix:
        return f"{ext.domain}.{ext.suffix}".lower().strip()
    return None


def load_fido2_supported() -> Set[str]:
    resp = requests.get("https://api.2fa.directory/v4/u2f.json")
    resp.raise_for_status()

    raw_supported = resp.json()
    root_domains = {
        extract_root_domain(domain)
        for domain in raw_supported.keys()
        if extract_root_domain(domain) is not None
    }
    return root_domains


def process_csv(
    csv_filename: str, fido2_supported: Set[str]
) -> tuple[list[str], list[str]]:
    supported = []
    unsupported = []

    with open(csv_filename, newline="") as f:
        reader = csv.DictReader(f)
        for row in reader:
            name = row.get("name", "").strip()
            url = row.get("login_uri", "").strip()
            domain = extract_root_domain(url)

            if not domain:
                print(f"[DEBUG] domain=None for entry {name!r} (uri={url!r})")
                unsupported.append(name)
                continue

            if domain in fido2_supported:
                supported.append(name)
            else:
                unsupported.append(name)

    return supported, unsupported


def export_to_org(
    supported: list[str], unsupported: list[str], output_filename: str
) -> None:
    with open(output_filename, "w") as f:
        f.write("* FIDO2 Setup Tracker\n")
        f.write("** ✅ Supported Accounts\n")
        for entry in sorted(set(supported)):
            f.write(f"- [ ] {entry}\n")
        f.write("\n** ❌ Unsupported / To Double-Check\n")
        for entry in sorted(set(unsupported)):
            f.write(f"- [ ] {entry}\n")


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python check_fido2_compat.py <bitwarden_export.csv>")
        sys.exit(1)

    csv_file = sys.argv[1]
    supported_sites = load_fido2_supported()
    supported, unsupported = process_csv(csv_file, supported_sites)
    export_to_org(supported, unsupported, "fido2_tracker.org")

    print("Done! Output written to fido2_tracker.org")
