from __future__ import annotations

import json
import os
from pathlib import Path
from typing import Any, MutableMapping


DEFAULT_SESSION_FILE = Path.home() / ".speedi" / "session.json"
ENV_SESSION_FILE = "SPEEDI_SESSION_FILE"


class Session(MutableMapping[str, Any]):
    """Dict-like session with optional persistence.

    - Backed by an in-memory dict
    - `mutated` flag set when changes occur
    - Save/Load from JSON file path
    - Path can be overridden by env `SPEEDI_SESSION_FILE`
    """

    def __init__(self) -> None:
        self._data: dict[str, Any] = {}
        self.mutated: bool = False
        # Eager load if file present
        self._path = self._resolve_path()
        self.load(silent=True)

    # MutableMapping
    def __getitem__(self, key: str) -> Any:
        return self._data[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self._data[key] = value
        self.mutated = True

    def __delitem__(self, key: str) -> None:
        del self._data[key]
        self.mutated = True

    def __iter__(self):
        return iter(self._data)

    def __len__(self) -> int:
        return len(self._data)

    # Helpers
    def get_path(self) -> Path:
        return self._path

    def _resolve_path(self) -> Path:
        override = os.getenv(ENV_SESSION_FILE)
        if override:
            return Path(override).expanduser().resolve()
        return DEFAULT_SESSION_FILE

    def load(self, *, silent: bool = False) -> None:
        path = self._path
        try:
            if path.exists():
                text = path.read_text(encoding="utf-8")
                if text.strip():
                    self._data = json.loads(text)
                else:
                    self._data = {}
            else:
                self._data = {}
        except Exception:
            if not silent:
                raise
        finally:
            self.mutated = False

    def save(self) -> None:
        path = self._path
        path.parent.mkdir(parents=True, exist_ok=True)
        tmp = path.with_suffix(".tmp")
        tmp.write_text(json.dumps(self._data, indent=2, sort_keys=True), encoding="utf-8")
        tmp.replace(path)
        self.mutated = False


# Global session instance
session = Session()
