"""Persistence for encrypted volume state."""

from __future__ import annotations

import os
import stat
from pathlib import Path

import yaml

from gaol.config import get_data_dir
from gaol.storage.models import VolumeState, VolumesStore


def _get_store_path() -> Path:
    """Get the volumes store file path."""
    return get_data_dir() / "volumes" / "volumes.yaml"


class VolumeStore:
    """Persistent storage for volume state.

    Stores volume metadata in a YAML file with restrictive permissions.
    """

    def __init__(self, store_path: Path | None = None) -> None:
        """Initialize the store."""
        self._store_path = store_path or _get_store_path()

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

    def _load(self) -> VolumesStore:
        """Load store from disk."""
        if not self._store_path.exists():
            return VolumesStore()

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

        return VolumesStore.model_validate(data)

    def _save(self, store: VolumesStore) -> None:
        """Save store to disk."""
        self._ensure_dir()

        # Write atomically
        temp_path = self._store_path.with_suffix(".tmp")
        with open(temp_path, "w") as f:
            yaml.dump(store.model_dump(mode="json"), f, default_flow_style=False)

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

    def save(self, volume: VolumeState) -> None:
        """Save or update a volume."""
        store = self._load()
        store.add_volume(volume)
        self._save(store)

    def get(self, name: str) -> VolumeState | None:
        """Get a volume by name."""
        store = self._load()
        return store.get_volume(name)

    def delete(self, name: str) -> bool:
        """Delete a volume."""
        store = self._load()
        if store.remove_volume(name):
            self._save(store)
            return True
        return False

    def list(self) -> list[VolumeState]:
        """List all volumes."""
        store = self._load()
        return store.list_volumes()

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