#!/usr/bin/env python3
import json
import os
import shutil
import sqlite3
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import List, Optional, Tuple


SCRIPT_DIR = Path(__file__).resolve().parent
VAULT_ROOT = SCRIPT_DIR.parent.parent
DEFAULT_DATA_DIR = VAULT_ROOT / "clippings" / "x bookmarks"


def eprint(msg: str) -> None:
    print(msg, file=sys.stderr)


def supported_browser_roots() -> List[Tuple[str, Path]]:
    home = Path.home()
    local_appdata = Path(os.environ.get("LOCALAPPDATA", ""))

    if os.name == "nt":
        roots = [
            ("chrome", local_appdata / "Google" / "Chrome" / "User Data"),
            ("chrome-beta", local_appdata / "Google" / "Chrome Beta" / "User Data"),
            ("brave", local_appdata / "BraveSoftware" / "Brave-Browser" / "User Data"),
        ]
    else:
        roots = [
            ("chrome", home / "Library" / "Application Support" / "Google" / "Chrome"),
            ("chrome-beta", home / "Library" / "Application Support" / "Google" / "Chrome Beta"),
            ("brave", home / "Library" / "Application Support" / "BraveSoftware" / "Brave-Browser"),
        ]

    return [(name, root) for name, root in roots if root.exists()]


def cookie_db_path(user_data_dir: Path, profile: str) -> Path:
    if os.name == "nt":
        return user_data_dir / profile / "Network" / "Cookies"
    return user_data_dir / profile / "Cookies"


def profile_names(user_data_dir: Path) -> List[str]:
    local_state = user_data_dir / "Local State"
    if local_state.exists():
        try:
            data = json.loads(local_state.read_text(encoding="utf-8"))
            info = data.get("profile", {}).get("info_cache", {})
            if info:
                return list(info.keys())
        except Exception:
            pass

    names = []
    for child in sorted(user_data_dir.iterdir()):
        if child.is_dir() and (child.name == "Default" or child.name.startswith("Profile ")):
            names.append(child.name)
    return names


def has_x_cookies(user_data_dir: Path, profile: str) -> bool:
    db = cookie_db_path(user_data_dir, profile)
    if not db.exists():
        return False

    tmp = tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False)
    tmp_path = Path(tmp.name)
    tmp.close()

    try:
        shutil.copy2(db, tmp_path)
        con = sqlite3.connect(tmp_path)
        cur = con.cursor()
        cur.execute(
            """
            select name
            from cookies
            where host_key in ('.x.com', '.twitter.com')
              and name in ('ct0', 'auth_token')
            """
        )
        names = {row[0] for row in cur.fetchall()}
        con.close()
        return {"ct0", "auth_token"}.issubset(names)
    except Exception:
        return False
    finally:
        try:
            tmp_path.unlink()
        except FileNotFoundError:
            pass


def autodetect_profile() -> Optional[Tuple[str, Path, str]]:
    for browser_name, root in supported_browser_roots():
        for profile in profile_names(root):
            if has_x_cookies(root, profile):
                return browser_name, root, profile
    return None


def resolve_ft_command() -> List[str]:
    env_cmd = os.environ.get("FT_COMMAND")
    if env_cmd:
        return [env_cmd]

    candidate = shutil.which("ft")
    if candidate:
        return [candidate]

    candidate = shutil.which("fieldtheory")
    if candidate:
        return [candidate]

    return []


def run_ft(argv: List[str]) -> int:
    ft_cmd = resolve_ft_command()
    if not ft_cmd:
        eprint(
            "Field Theory CLI was not found. Install it and re-run this command, "
            "or set FT_COMMAND to the executable path."
        )
        eprint(f"Expected bookmark data dir: {DEFAULT_DATA_DIR}")
        return 1

    env = os.environ.copy()
    env.setdefault("FT_DATA_DIR", str(DEFAULT_DATA_DIR))
    DEFAULT_DATA_DIR.mkdir(parents=True, exist_ok=True)

    args = ft_cmd + argv

    if argv and argv[0] == "sync":
        explicit_dir = "--chrome-user-data-dir" in argv
        explicit_profile = "--chrome-profile-directory" in argv
        if not explicit_dir and not explicit_profile and "--api" not in argv:
            detected = autodetect_profile()
            if detected is None:
                eprint(
                    "No supported logged-in X browser profile was found. "
                    "Open x.com in Chrome/Chrome Beta/Brave and log in, or run sync --api."
                )
                return 1
            browser_name, root, profile = detected
            eprint(f"Using {browser_name} profile {profile} for X session discovery.")
            args.extend(["--chrome-user-data-dir", str(root), "--chrome-profile-directory", profile])

    proc = subprocess.run(args, env=env)
    return proc.returncode


def main() -> int:
    return run_ft(sys.argv[1:])


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