import yaml
import threading
from pathlib import Path
from typing import Dict, Iterator, Optional, Union
from collections.abc import MutableMapping

from sibi_flux.core import SecureResource

class GlobalFieldRegistry(SecureResource, MutableMapping):
    """
    [DEPRECATED] Use sibi_flux.datacube.field_mapper.FieldTranslationManager instead.

    Acts as the source of truth for field translations (Database Column -> English Attribute).
    Backed by a local YAML file. Thread-safe.
    Hardened with SecureResource for sandboxed I/O.
    """

    def __init__(self, file_path: Union[str, Path]):
        """
        Initialize the registry.

        Args:
            file_path: Path to the YAML file backing this registry.
        """
        super().__init__()
        self.file_path = self.get_secure_path(file_path)
        self._data: Dict[str, str] = {}
        self._dirty = False
        self._lock = threading.RLock()
        self._load()

    def _load(self) -> None:
        """Load state from the YAML file."""
        with self._lock:
            if self.file_path.exists():
                try:
                    with self.open_secure(self.file_path, "r", encoding="utf-8") as f:
                        content = yaml.safe_load(f)
                        if content and isinstance(content, dict):
                            self._data = content
                        else:
                            self._data = {}
                except Exception:
                    self._data = {}
            else:
                self._data = {}

    def save(self) -> None:
        """Persist changes to the YAML file if any changes were made."""
        with self._lock:
            if not self._dirty:
                return

            # Ensure directory exists
            self.file_path.parent.mkdir(parents=True, exist_ok=True)

            with self.open_secure(self.file_path, "w", encoding="utf-8") as f:
                for key, value in sorted(self._data.items()):
                    # Dump single line
                    line = yaml.dump(
                        {key: value},
                        sort_keys=False,
                        allow_unicode=True,
                        default_flow_style=False,
                    ).strip()

                    # Append comment if translation matches original
                    if key == value:
                        line += " # Translation missing"

                    f.write(line + "\n")

            self._dirty = False

    def register_field(
        self,
        original_name: str,
        suggested_translation: Optional[str] = None,
        force_update: bool = False,
    ) -> None:
        """
        Register a field if it does not exist, or update if force_update is True.

        Args:
            original_name: The original database column name.
            suggested_translation: Proposed English translation.
            force_update: If True, overwrite existing translation.
        """
        with self._lock:
            if original_name in self._data:
                if force_update and suggested_translation:
                    if self._data[original_name] != suggested_translation:
                        self._data[original_name] = suggested_translation
                        self._dirty = True
            else:
                # New field - use suggestion or default to identity
                val = suggested_translation if suggested_translation else original_name
                self._data[original_name] = val
                self._dirty = True

    # --- MutableMapping Implementation ---

    def __getitem__(self, key: str) -> str:
        with self._lock:
            return self._data[key]

    def __setitem__(self, key: str, value: str) -> None:
        with self._lock:
            if self._data.get(key) != value:
                self._data[key] = value
                self._dirty = True

    def __delitem__(self, key: str) -> None:
        with self._lock:
            if key in self._data:
                del self._data[key]
                self._dirty = True

    def __iter__(self) -> Iterator[str]:
        with self._lock:
            return iter(list(self._data))

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