"""State file read/write.

Server-managed runtime state stored at:
  ~/.local/state/synology-mcp/{instance_id}/state.yaml
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml
from pydantic import BaseModel, Field


class ApiInfoEntry(BaseModel):
    """Cached API endpoint info from SYNO.API.Info."""

    path: str
    min_version: int
    max_version: int
    request_format: str | None = None


class ServerState(BaseModel):
    """Persistent server state."""

    api_info_cache: dict[str, ApiInfoEntry] = Field(default_factory=dict)
    negotiated_versions: dict[str, int] = Field(default_factory=dict)
    recycle_bin_status: dict[str, bool] = Field(default_factory=dict)
    last_connected: str | None = None
    dsm_version: str | None = None
    hostname: str | None = None


def _state_path(instance_id: str) -> Path:
    """Get the state file path for an instance."""
    return Path.home() / ".local" / "state" / "synology-mcp" / instance_id / "state.yaml"


def load_state(instance_id: str) -> ServerState:
    """Load state from disk. Returns default state if file doesn't exist."""
    path = _state_path(instance_id)
    if not path.exists():
        return ServerState()

    raw_text = path.read_text(encoding="utf-8")
    raw: dict[str, Any] = yaml.safe_load(raw_text) or {}
    return ServerState(**raw)


def save_state(instance_id: str, state: ServerState) -> None:
    """Save state to disk. Creates directories if needed."""
    path = _state_path(instance_id)
    path.parent.mkdir(parents=True, exist_ok=True)

    data = state.model_dump(mode="json", exclude_none=True)
    raw_text = yaml.dump(data, default_flow_style=False, sort_keys=False)

    # Add header comment
    header = "# Auto-generated by synology-mcp. Do not edit.\n"
    path.write_text(header + raw_text, encoding="utf-8")
