"""Auto-extract Slack xoxc_token and d_cookie from Chrome.

Works on Linux and macOS by reading Chrome's Local Storage (LevelDB)
for the xoxc token and Chrome's Cookies database for the d cookie.

Requires: pycookiecheat
"""

from __future__ import annotations

import logging
import re
import subprocess
import sys
from pathlib import Path
from typing import cast

logger = logging.getLogger(__name__)


def _chrome_base_dir() -> Path:
    """Return the Chrome user data directory for the current platform."""
    if sys.platform == "darwin":
        return Path.home() / "Library" / "Application Support" / "Google" / "Chrome"
    return Path.home() / ".config" / "google-chrome"


_DEFAULT_PROFILES = ["Profile 1", "Default", "Profile 2", "Profile 3"]


def get_d_cookie(
    slack_url: str = "https://redhat.enterprise.slack.com",
    profiles: list[str] | None = None,
) -> str | None:
    """Extract the Slack ``d`` cookie from Chrome's encrypted cookie store.

    Returns the cookie value or ``None`` if not found.
    """
    try:
        from pycookiecheat import chrome_cookies  # type: ignore[import-untyped]
    except ImportError:
        logger.debug("pycookiecheat not installed, cannot extract d_cookie")
        return None

    chrome_base = _chrome_base_dir()

    for profile in profiles or _DEFAULT_PROFILES:
        cookie_file = chrome_base / profile / "Cookies"
        if not cookie_file.exists():
            continue
        try:
            result = chrome_cookies(slack_url, cookie_file=str(cookie_file))
            if "d" in result:
                logger.info("Found d_cookie in Chrome profile: %s", profile)
                return cast(str, result["d"])  # Keep URL-encoded — Slack requires it
        except Exception as exc:
            logger.debug("Error reading cookies from %s: %s", profile, exc)

    return None


def get_xoxc_token(profiles: list[str] | None = None) -> str | None:
    """Extract the Slack ``xoxc`` token from Chrome's Local Storage (LevelDB).

    Searches ``.ldb`` files newest-first and returns the first match.
    """
    chrome_base = _chrome_base_dir()
    pattern = re.compile(r"xoxc-[a-zA-Z0-9_-]{77,}")

    for profile in profiles or _DEFAULT_PROFILES:
        local_storage_dir = chrome_base / profile / "Local Storage" / "leveldb"
        if not local_storage_dir.exists():
            continue

        try:
            ldb_files = sorted(
                local_storage_dir.glob("*.ldb"),
                key=lambda f: f.stat().st_mtime,
                reverse=True,
            )
            for ldb_file in ldb_files:
                result = subprocess.run(
                    ["strings", str(ldb_file)],
                    capture_output=True,
                    text=True,
                )
                if result.returncode != 0:
                    continue
                matches = pattern.findall(result.stdout)
                if matches:
                    logger.info("Found xoxc_token in Chrome profile: %s", profile)
                    return cast(str, matches[0])
        except Exception as exc:
            logger.debug("Error reading Local Storage from %s: %s", profile, exc)

    return None


def auto_extract_slack_creds() -> dict[str, str | None]:
    """Attempt to extract both Slack credentials from Chrome.

    The d cookie is stored under .slack.com by Chrome, so we try slack.com
    and app.slack.com (the actual web client domain) as well as the
    enterprise domain.

    Returns a dict with keys ``xoxc_token`` and ``d_cookie``, values may be ``None``.
    """
    d_cookie = None
    for url in (
        "https://slack.com",
        "https://app.slack.com",
        "https://redhat.enterprise.slack.com",
    ):
        d_cookie = get_d_cookie(url)
        if d_cookie:
            break

    return {
        "xoxc_token": get_xoxc_token(),
        "d_cookie": d_cookie,
    }
