"""Storage backends for the alignment enclave — same pattern as nostrsocial."""

from __future__ import annotations

import hashlib
import json
import os
from abc import ABC, abstractmethod
from typing import Optional


class StorageBackend(ABC):
    """Abstract storage backend for alignment state."""

    @abstractmethod
    def save(self, data: dict) -> None:
        ...

    @abstractmethod
    def load(self) -> Optional[dict]:
        ...


class MemoryStorage(StorageBackend):
    """In-memory storage — for testing and ephemeral use."""

    def __init__(self) -> None:
        self._data: Optional[dict] = None

    def save(self, data: dict) -> None:
        self._data = data

    def load(self) -> Optional[dict]:
        return self._data


class FileStorage(StorageBackend):
    """File-based storage with integrity verification."""

    def __init__(self, path: str) -> None:
        self._path = path
        self._checksum_path = path + ".sha256"

    def save(self, data: dict) -> None:
        os.makedirs(os.path.dirname(self._path), exist_ok=True)
        tmp = self._path + ".tmp"
        checksum_tmp = self._checksum_path + ".tmp"

        # Serialize deterministically for checksum
        json_str = json.dumps(data, indent=2, default=str, sort_keys=True)
        checksum = hashlib.sha256(json_str.encode()).hexdigest()

        try:
            with open(tmp, "w") as f:
                f.write(json_str)
            with open(checksum_tmp, "w") as f:
                f.write(checksum)
            os.replace(tmp, self._path)
            os.replace(checksum_tmp, self._checksum_path)
        except Exception:
            for p in (tmp, checksum_tmp):
                if os.path.exists(p):
                    os.remove(p)
            raise

    def load(self) -> Optional[dict]:
        if not os.path.exists(self._path):
            return None
        with open(self._path, "r") as f:
            data = json.load(f)
        # Verify checksum if present
        if os.path.exists(self._checksum_path):
            json_str = json.dumps(data, indent=2, default=str, sort_keys=True)
            expected = hashlib.sha256(json_str.encode()).hexdigest()
            with open(self._checksum_path) as f:
                actual = f.read().strip()
            if expected != actual:
                raise RuntimeError(
                    "Storage integrity check FAILED. "
                    "File may be corrupted or tampered with. "
                    f"Expected checksum {expected[:16]}..., got {actual[:16]}..."
                )
        return data
