from __future__ import annotations

import sqlite3
from pathlib import Path

import pytest

from reddit_mcp import cookie_manager


def _write_cookies_db(path: Path, *, reddit_rows: int = 0, other_rows: int = 0) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    with sqlite3.connect(path) as conn:
        conn.execute("create table cookies (host_key text)")
        for _ in range(reddit_rows):
            conn.execute("insert into cookies(host_key) values (?)", (".reddit.com",))
        for _ in range(other_rows):
            conn.execute("insert into cookies(host_key) values (?)", (".example.com",))
        conn.commit()


def _candidate(
    *,
    user_data_dir: Path,
    profile_name: str,
    profile_dir: Path,
    cookies_db: Path,
) -> cookie_manager.BrowserProfileCandidate:
    return cookie_manager.BrowserProfileCandidate(
        browser_label="Google Chrome",
        executable_path=user_data_dir / "chrome",
        user_data_dir=user_data_dir,
        profile_name=profile_name,
        profile_dir=profile_dir,
        cookies_db=cookies_db,
        reddit_cookie_rows=1,
        cookies_mtime=123.0,
    )


def test_discover_browser_profile_candidates_supports_network_cookie_db(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    browser_bin = tmp_path / "chrome"
    browser_bin.write_text("", encoding="utf-8")
    user_data_dir = tmp_path / "User Data"
    profile_dir = user_data_dir / "Profile 3"
    cookies_db = profile_dir / "Network" / "Cookies"
    _write_cookies_db(cookies_db, reddit_rows=2)

    monkeypatch.setattr(
        cookie_manager,
        "_known_browser_installations",
        lambda: [("Google Chrome", browser_bin, user_data_dir)],
    )

    candidates = cookie_manager._discover_browser_profile_candidates()

    assert len(candidates) == 1
    assert candidates[0].cookies_db == cookies_db
    assert candidates[0].reddit_cookie_rows == 2


def test_profile_paths_to_copy_is_minimal_and_cookie_focused(tmp_path: Path) -> None:
    user_data_dir = tmp_path / "User Data"
    profile_dir = user_data_dir / "Profile 7"
    cookies_db = profile_dir / "Network" / "Cookies"
    _write_cookies_db(cookies_db, reddit_rows=1)

    candidate = _candidate(
        user_data_dir=user_data_dir,
        profile_name="Profile 7",
        profile_dir=profile_dir,
        cookies_db=cookies_db,
    )

    paths = cookie_manager._profile_paths_to_copy(candidate)

    assert Path("Network/Cookies") in paths
    assert Path("Network/Cookies-wal") in paths
    assert Path("Preferences") in paths
    assert Path("Secure Preferences") in paths
    assert all("Cache" not in str(path) for path in paths)


def test_copy_profile_workspace_copies_minimum_required_files(tmp_path: Path) -> None:
    user_data_dir = tmp_path / "User Data"
    profile_dir = user_data_dir / "Profile 2"
    cookies_db = profile_dir / "Network" / "Cookies"
    _write_cookies_db(cookies_db, reddit_rows=1)
    (profile_dir / "Network" / "Cookies-wal").write_text("wal", encoding="utf-8")
    (profile_dir / "Preferences").write_text("prefs", encoding="utf-8")
    (profile_dir / "Secure Preferences").write_text("secure", encoding="utf-8")
    (profile_dir / "History").write_text("history", encoding="utf-8")
    (profile_dir / "Cache").mkdir(parents=True, exist_ok=True)
    (profile_dir / "Cache" / "tmp.bin").write_text("cache", encoding="utf-8")
    (user_data_dir / "Local State").write_text("{}", encoding="utf-8")

    candidate = _candidate(
        user_data_dir=user_data_dir,
        profile_name="Profile 2",
        profile_dir=profile_dir,
        cookies_db=cookies_db,
    )

    workspace = tmp_path / "workspace"
    cookie_manager._copy_profile_workspace(candidate, workspace)

    copied_profile = workspace / "Profile 2"
    assert (copied_profile / "Network" / "Cookies").exists()
    assert (copied_profile / "Network" / "Cookies-wal").exists()
    assert (copied_profile / "Preferences").exists()
    assert (copied_profile / "Secure Preferences").exists()
    assert not (copied_profile / "History").exists()
    assert not (copied_profile / "Cache").exists()
    assert (workspace / "Local State").exists()


def test_copy_profile_workspace_windows_error_points_to_shutdown_browser(
    monkeypatch: pytest.MonkeyPatch,
    tmp_path: Path,
) -> None:
    user_data_dir = tmp_path / "User Data"
    profile_dir = user_data_dir / "Profile 11"
    cookies_db = profile_dir / "Network" / "Cookies"
    _write_cookies_db(cookies_db, reddit_rows=1)

    candidate = _candidate(
        user_data_dir=user_data_dir,
        profile_name="Profile 11",
        profile_dir=profile_dir,
        cookies_db=cookies_db,
    )

    real_copy2 = cookie_manager.shutil.copy2

    def fake_copy2(src, dst, *args, **kwargs):  # type: ignore[no-untyped-def]
        if Path(src) == cookies_db:
            raise PermissionError("locked")
        return real_copy2(src, dst, *args, **kwargs)

    monkeypatch.setattr(cookie_manager.shutil, "copy2", fake_copy2)
    monkeypatch.setattr(cookie_manager.sys, "platform", "win32")

    with pytest.raises(RuntimeError, match="--shutdown-browser"):
        cookie_manager._copy_profile_workspace(candidate, tmp_path / "workspace")
