"""Persistence for remote host registry."""

from __future__ import annotations

import os
import stat
from pathlib import Path

import yaml

from gaol.config import get_data_dir
from gaol.remote.models import HostsRegistry, StoredHost


def _get_remote_dir() -> Path:
    """Get the remote data directory."""
    return get_data_dir() / "remote"


class HostStore:
    """Persistent storage for remote host registry.

    Stores host configurations in a YAML file with restrictive permissions.
    """

    def __init__(self, store_dir: Path | None = None) -> None:
        """Initialize the store."""
        self._store_dir = store_dir or _get_remote_dir()
        self._hosts_path = self._store_dir / "hosts.yaml"

    def _ensure_dir(self) -> None:
        """Ensure store directory exists with proper permissions."""
        self._store_dir.mkdir(parents=True, exist_ok=True)
        os.chmod(self._store_dir, stat.S_IRWXU)  # 700

    def _load_registry(self) -> HostsRegistry:
        """Load hosts registry from disk."""
        if not self._hosts_path.exists():
            return HostsRegistry()

        with open(self._hosts_path) as f:
            data = yaml.safe_load(f) or {}

        return HostsRegistry.model_validate(data)

    def _save_registry(self, registry: HostsRegistry) -> None:
        """Save hosts registry to disk."""
        self._ensure_dir()

        temp_path = self._hosts_path.with_suffix(".tmp")
        with open(temp_path, "w") as f:
            yaml.dump(registry.model_dump(mode="json"), f, default_flow_style=False)

        os.chmod(temp_path, stat.S_IRUSR | stat.S_IWUSR)  # 600
        temp_path.rename(self._hosts_path)

    # Host operations

    def save_host(self, host: StoredHost) -> None:
        """Save or update a host."""
        registry = self._load_registry()
        registry.add_host(host)
        self._save_registry(registry)

    def get_host(self, name: str) -> StoredHost | None:
        """Get a host by name."""
        registry = self._load_registry()
        return registry.get_host(name)

    def delete_host(self, name: str) -> bool:
        """Delete a host."""
        registry = self._load_registry()
        if registry.remove_host(name):
            self._save_registry(registry)
            return True
        return False

    def list_hosts(self) -> list[StoredHost]:
        """List all hosts."""
        registry = self._load_registry()
        return registry.list_hosts()

    def host_exists(self, name: str) -> bool:
        """Check if a host exists."""
        return self.get_host(name) is not None

    def update_host_state(self, host: StoredHost) -> None:
        """Update a host's state (same as save_host, but semantic)."""
        self.save_host(host)
