"""{{ display_name }} MCP server — generated by mcpify. Do not hand-edit.

Persists a credential to the OS-native keychain when available (macOS
Keychain, Windows Credential Manager, Linux Secret Service, via the
`keyring` package), falling back to an AES-256-GCM-encrypted local file
when the platform backend is unavailable (e.g. no D-Bus secret-service
daemon running, common in minimal containers) — REQ-2.3.5.
"""

from __future__ import annotations

import hashlib
import json
import os
import stat
from pathlib import Path

import keyring
import keyring.errors
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

from . import logger as _logger_module

SERVICE_NAME = "{{ project_name }}"

log = _logger_module.get_logger(__name__)


def _config_dir() -> Path:
    return Path(os.environ.get("HOME", ".")) / ".{{ project_name }}"


def _fallback_file() -> Path:
    return _config_dir() / "credentials.enc"


def _encryption_key() -> bytes:
    """Derived from a machine/user-specific value so the encrypted
    fallback file isn't portable to another machine by design, mirroring
    the OS keychain's own implicit scoping.
    """
    home = os.environ.get("HOME", "")
    return hashlib.sha256(f"{home}{SERVICE_NAME}".encode()).digest()


def _read_store() -> dict[str, str]:
    try:
        contents = _fallback_file().read_text()
    except OSError:
        return {}
    try:
        loaded = json.loads(contents)
    except json.JSONDecodeError:
        return {}
    return loaded if isinstance(loaded, dict) else {}


def _write_store(store: dict[str, str]) -> None:
    config_dir = _config_dir()
    config_dir.mkdir(parents=True, exist_ok=True)
    fallback_file = _fallback_file()
    fallback_file.write_text(json.dumps(store))
    os.chmod(config_dir, stat.S_IRWXU)
    os.chmod(fallback_file, stat.S_IRUSR | stat.S_IWUSR)


def _save_to_file(account: str, value: str) -> None:
    aesgcm = AESGCM(_encryption_key())
    nonce = os.urandom(12)
    ciphertext = aesgcm.encrypt(nonce, value.encode(), None)

    store = _read_store()
    store[account] = f"{nonce.hex()}:{ciphertext.hex()}"
    _write_store(store)


def _load_from_file(account: str) -> str | None:
    store = _read_store()
    raw = store.get(account)
    if raw is None:
        return None
    nonce_hex, _, ciphertext_hex = raw.partition(":")

    aesgcm = AESGCM(_encryption_key())
    plaintext = aesgcm.decrypt(bytes.fromhex(nonce_hex), bytes.fromhex(ciphertext_hex), None)
    return plaintext.decode()


def _delete_from_file(account: str) -> None:
    store = _read_store()
    if store.pop(account, None) is not None:
        _write_store(store)


def save_credential(account: str, value: str) -> None:
    try:
        keyring.set_password(SERVICE_NAME, account, value)
    except keyring.errors.KeyringError as err:
        log.warning(
            "OS keychain unavailable; falling back to encrypted file storage", error=str(err)
        )
        _save_to_file(account, value)


def load_credential(account: str) -> str | None:
    try:
        return keyring.get_password(SERVICE_NAME, account)
    except keyring.errors.KeyringError:
        return _load_from_file(account)


def delete_credential(account: str) -> None:
    try:
        keyring.delete_password(SERVICE_NAME, account)
    except keyring.errors.PasswordDeleteError:
        pass
    except keyring.errors.KeyringError:
        _delete_from_file(account)
