"""Persistent token storage for CLI authentication."""

from __future__ import annotations

import json
import os
import platform
import stat
import time
from pathlib import Path
from typing import Optional


APP_NAME = "oncecheck"
TOKEN_TTL_SECONDS = 7 * 24 * 3600  # 7 days


def _token_dir() -> Path:
    system = platform.system()
    if system == "Darwin":
        base = Path.home() / "Library" / "Application Support"
    elif system == "Windows":
        base = Path(os.environ.get("APPDATA", str(Path.home() / "AppData" / "Roaming")))
    else:
        base = Path(os.environ.get("XDG_CONFIG_HOME", str(Path.home() / ".config")))
    return base / APP_NAME


def _token_path() -> Path:
    return _token_dir() / "token.json"


def _set_file_permissions(path: Path, is_dir: bool = False) -> None:
    """Restrict to owner-only: 0o700 for dirs, 0o600 for files."""
    try:
        if platform.system() != "Windows":
            if is_dir:
                os.chmod(path, stat.S_IRWXU)  # 0o700
            else:
                os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)  # 0o600
    except OSError:
        pass


def save_token(data: dict) -> Path:
    """Write token data to disk with restricted permissions and return the path."""
    # Stamp the token with an issued-at time for expiration checks
    if "issued_at" not in data:
        data["issued_at"] = time.time()

    path = _token_path()
    path.parent.mkdir(parents=True, exist_ok=True)

    # Set restrictive permissions on directory (needs execute for traversal)
    _set_file_permissions(path.parent, is_dir=True)

    path.write_text(json.dumps(data, indent=2))
    _set_file_permissions(path)
    return path


def load_token() -> Optional[dict]:
    """Load saved token, or return None if absent / invalid / expired."""
    path = _token_path()
    if not path.exists():
        return None
    try:
        data = json.loads(path.read_text())
    except (json.JSONDecodeError, OSError):
        return None

    # Check token expiration
    issued_at = data.get("issued_at", 0)
    if time.time() - issued_at > TOKEN_TTL_SECONDS:
        clear_token()
        return None

    return data


def clear_token() -> None:
    """Delete the saved token file."""
    path = _token_path()
    if path.exists():
        path.unlink()
