"""Credential and configuration storage for the MLD client.

Stores per-host auth tokens in ~/.config/mld/credentials.json with
restrictive file permissions (0600). Follows XDG conventions.
"""

from __future__ import annotations

import json
import os
import stat
from pathlib import Path
from typing import Any


def _config_dir() -> Path:
    """Return the MLD config directory, respecting XDG_CONFIG_HOME."""
    xdg = os.environ.get("XDG_CONFIG_HOME")
    if xdg:
        return Path(xdg) / "mld"
    return Path.home() / ".config" / "mld"


def _config_path() -> Path:
    return _config_dir() / "credentials.json"


def _empty_config() -> dict[str, Any]:
    return {"version": 1, "default_host": None, "hosts": {}}


def load_config() -> dict[str, Any]:
    """Load the credentials config file. Returns empty config if missing."""
    path = _config_path()
    if not path.exists():
        return _empty_config()
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
        if not isinstance(data, dict) or "hosts" not in data:
            return _empty_config()
        return data
    except (json.JSONDecodeError, OSError):
        return _empty_config()


def save_config(config: dict[str, Any]) -> None:
    """Write the credentials config file with restrictive permissions."""
    path = _config_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(config, indent=2) + "\n", encoding="utf-8")
    path.chmod(stat.S_IRUSR | stat.S_IWUSR)  # 0600


def _normalize_host(host: str) -> str:
    """Strip trailing slash for consistent key lookup."""
    return host.rstrip("/")


def get_stored_token(host: str) -> str | None:
    """Return the stored token for a host, or None."""
    config = load_config()
    entry = config.get("hosts", {}).get(_normalize_host(host))
    if entry:
        return entry.get("token")
    return None


def store_token(
    host: str,
    token: str,
    username: str,
    expires_at: str | None = None,
) -> None:
    """Store a token for a host and set it as the default."""
    config = load_config()
    host = _normalize_host(host)
    config["hosts"][host] = {
        "token": token,
        "username": username,
        "expires_at": expires_at,
    }
    config["default_host"] = host
    save_config(config)


def remove_token(host: str) -> None:
    """Remove stored credentials for a host."""
    config = load_config()
    host = _normalize_host(host)
    config["hosts"].pop(host, None)
    if config.get("default_host") == host:
        config["default_host"] = None
    save_config(config)


def get_default_host() -> str | None:
    """Return the default host URL, or None."""
    config = load_config()
    return config.get("default_host")


def set_default_host(host: str) -> None:
    """Set the default host URL."""
    config = load_config()
    config["default_host"] = _normalize_host(host)
    save_config(config)


def get_stored_username(host: str) -> str | None:
    """Return the stored username for a host, or None."""
    config = load_config()
    entry = config.get("hosts", {}).get(_normalize_host(host))
    if entry:
        return entry.get("username")
    return None
