"""
GUARDiA ITSM — 자격증명 암호화 공통 유틸리티

외부 연동 자격증명(API 키·시크릿·토큰·SNMP 커뮤니티 문자열 등)을 DB에 평문으로
저장하지 않기 위한 AES-256-GCM 암호화/복호화 모듈. 여러 라우터(jira_sync·multicloud·
ncloud·public_api_hub·snmp_discovery·sso_provider·upstage_ocr 등)가 공유한다.

키 소스: GUARDIA_ENC_KEY 환경변수 (문자열을 UTF-8 인코딩 후 32바이트로 패딩/절단).
        core/seed.py · routers/citizen_portal.py 와 동일한 컨벤션 — 운영 배포 시
        반드시 32자 이상의 고유 값으로 설정할 것 (미설정 시 데모 기본값 사용).
저장 형식: base64(nonce[12] + ciphertext + GCM tag[16])
"""
from __future__ import annotations

import base64
import os

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


def _enc_key() -> bytes:
    raw = os.environ.get("GUARDIA_ENC_KEY", "guardia-demo-key-32bytes-padding!").encode("utf-8")
    return raw[:32].ljust(32, b"\x00")


def encrypt_secret(plain: str | None) -> str | None:
    """평문 자격증명을 AES-256-GCM으로 암호화하여 base64 문자열로 반환한다."""
    if not plain:
        return plain
    nonce = os.urandom(12)
    ct = AESGCM(_enc_key()).encrypt(nonce, plain.encode("utf-8"), None)
    return base64.b64encode(nonce + ct).decode("ascii")


def decrypt_secret(enc_value: str | None) -> str | None:
    """encrypt_secret()으로 암호화된 문자열을 복호화한다.

    평문으로 저장된 레거시 값(이번 암호화 적용 이전 데이터)이나 손상된 값을 만나면
    예외를 전파하지 않고 입력값을 그대로 반환한다 — Fail-Safe 원칙(CLAUDE.md)에 따라
    기존 연동이 끊기지 않도록 한다.
    """
    if not enc_value:
        return enc_value
    try:
        raw = base64.b64decode(enc_value, validate=True)
        nonce, ct = raw[:12], raw[12:]
        return AESGCM(_enc_key()).decrypt(nonce, ct, None).decode("utf-8")
    except Exception:
        return enc_value


# kubernetes.py 등에서 참조하는 이름과 호환되는 별칭
encrypt_password = encrypt_secret
decrypt_password = decrypt_secret
