"""secrets.vault — AES-256-GCM encrypted secret storage."""
from __future__ import annotations
import base64
import hashlib
import os
from typing import Optional
from agentpaas.config import settings


def _derive_key(master_key: str) -> bytes:
    return hashlib.sha256(master_key.encode()).digest()


def encrypt(plaintext: str) -> str:
    """Encrypt with AES-256-GCM. Requires cryptography package."""
    from cryptography.hazmat.primitives.ciphers.aead import AESGCM
    key = _derive_key(settings.master_key)
    nonce = os.urandom(12)
    aes = AESGCM(key)
    ct = aes.encrypt(nonce, plaintext.encode(), None)
    return base64.b64encode(nonce + ct).decode()


def decrypt(encrypted: str) -> str:
    """Decrypt AES-256-GCM. Handles legacy b64: prefix for migration."""
    if encrypted.startswith("b64:"):
        # Legacy format — log warning, decode but flag for re-encryption
        from agentpaas.observability.logging import logger
        logger.warning("SEC-09: Legacy base64 secret detected. Re-encrypt with proper AES.")
        return base64.b64decode(encrypted[4:]).decode()
    from cryptography.hazmat.primitives.ciphers.aead import AESGCM
    key = _derive_key(settings.master_key)
    raw = base64.b64decode(encrypted)
    nonce, ct = raw[:12], raw[12:]
    aes = AESGCM(key)
    return aes.decrypt(nonce, ct, None).decode()


def store_secret(tenant_id: str, name: str, value: str, environment: str = "production"):
    from agentpaas.db.session import get_db
    from agentpaas.db.models import gen_id, now_utc
    db = get_db()
    enc = encrypt(value)
    existing = db.fetchone("SELECT id FROM secrets WHERE tenant_id=? AND name=? AND environment=?",
                           (tenant_id, name, environment)) if db.fetchone("SELECT name FROM sqlite_master WHERE type='table' AND name='secrets'", ()) else None
    # Create secrets table if not exists
    db.execute("""CREATE TABLE IF NOT EXISTS secrets (
        id TEXT PRIMARY KEY, tenant_id TEXT, name TEXT, encrypted_value TEXT,
        environment TEXT DEFAULT 'production', created_by TEXT, updated_at TEXT)""")
    if existing:
        db.execute("UPDATE secrets SET encrypted_value=?, updated_at=? WHERE id=?", (enc, now_utc(), existing["id"]))
    else:
        db.execute("INSERT INTO secrets (id, tenant_id, name, encrypted_value, environment, updated_at) VALUES (?,?,?,?,?,?)",
                   (gen_id("sec_"), tenant_id, name, enc, environment, now_utc()))
    db.commit()


def get_secret(tenant_id: str, name: str, environment: str = "production") -> Optional[str]:
    from agentpaas.db.session import get_db
    db = get_db()
    row = db.fetchone("SELECT encrypted_value FROM secrets WHERE tenant_id=? AND name=? AND environment=?",
                      (tenant_id, name, environment))
    return decrypt(row["encrypted_value"]) if row else None
