#!/usr/bin/env python3
"""
Hämta Cibello-prod-hemligheter från AWS SSM och skriv /opt/cibello-platform/.env.

SSM är enda sanningskällan. Kör detta vid varje deploy INNAN applikationen startas om.
Inga värden loggas. set +x aktiveras automatiskt.
"""
import json
import os
import subprocess
import sys
from pathlib import Path

REGION = os.environ.get("AWS_REGION", "eu-north-1")
SSM_PREFIX = "/cibello/prod"
ENV_PATH = Path(os.environ.get("ENV_PATH", "/opt/cibello-platform/.env"))

# Icke-hemliga värden som ändå behöver styras centralt.
# Dessa kan med fördel också flyttas till SSM (String/SecureString) senare.
STATIC_CONFIG = {
    "NODE_ENV": "production",
    "API_PORT": "4000",
    "ADMIN_PORT": "5173",
    "API_BASE_URL": "https://api.cibello.app",
    "VITE_API_BASE_URL": "https://api.cibello.app",
    "CORS_ORIGINS": "https://cibello.app,https://admin.cibello.app,https://api.cibello.app",
    "REDIS_URL": "redis://localhost:6379",
    "LOG_LEVEL": "info",
    "AAMOS_MODE": "gemini",
    "AAMOS_API_URL": "https://amos.aamos.systems",
    "EOC_URL": "https://eoc.aamos.systems",
    "AAMOS_TIMEOUT_MS": "60000",
    # GEMINI_MODEL hämtas från SSM (String-typ)
    "GEMINI_TIMEOUT_MS": "60000",
    "GEMINI_DAILY_BUDGET_USD": "25",
    "ENTITLEMENT_TTL_HOURS": "24",
    "ENTITLEMENT_GRACE_DAYS": "7",
    "JWT_ACCESS_TTL_SECONDS": "900",
    "JWT_REFRESH_TTL_SECONDS": "2592000",
    "S3_MODE": "aws",
    "S3_BUCKET": "cibello-production",
    "S3_REGION": "eu-north-1",
    "SMTP_HOST": "mail.aamos.systems",
    "SMTP_PORT": "587",
    "SMTP_SECURE": "false",
    "SMTP_USER": "hello@cibello.app",
    "MAIL_FROM": "hello@cibello.app",
    "EMAIL_MODE": "smtp",
    "EXPO_PUSH_ENABLED": "false",
    "DATABASE_CA_CERT": "/opt/cibello-platform/certs/rds-global-bundle.pem",
}

# SSM-parameter → env-var. Värden från SSM skriver över STATIC_CONFIG om de krockar.
SSM_MAP = {
    "aamos-api-key": "AAMOS_API_KEY",
    "db-password": "DB_PASSWORD",  # används för att bygga DATABASE_URL
    "entitlement-signing-secret": "ENTITLEMENT_SIGNING_SECRET",
    "eoc-push-token": "EOC_PUSH_TOKEN",
    "gemini-api-key": "GEMINI_API_KEY",
    "gemini-model": "GEMINI_MODEL",
    "jwt-access-secret": "JWT_ACCESS_SECRET",
    "jwt-refresh-secret": "JWT_REFRESH_SECRET",
    "smtp-pass": "SMTP_PASS",
    "ops-token": "OPS_TOKEN",
    # Följande är valfria just nu men bör ligga i SSM
    "google-service-account-json": "GOOGLE_SERVICE_ACCOUNT_JSON",
}


def get_parameters(names: list[str]) -> dict[str, str]:
    if not names:
        return {}
    out: dict[str, str] = {}
    invalid: list[str] = []
    # AWS GetParameters max 10 namn per anrop.
    for i in range(0, len(names), 10):
        batch = names[i : i + 10]
        cmd = [
            "aws", "ssm", "get-parameters",
            "--names", *batch,
            "--with-decryption",
            "--region", REGION,
        ]
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        data = json.loads(result.stdout)
        for p in data.get("Parameters", []):
            out[p["Name"]] = p["Value"].strip()
        invalid.extend(data.get("InvalidParameters", []))
    for inv in invalid:
        print(f"[sync-env] WARN: SSM-parameter saknas: {inv}", file=sys.stderr)
    return out


def build_env(ssm: dict[str, str]) -> dict[str, str]:
    env = dict(STATIC_CONFIG)

    for short, var in SSM_MAP.items():
        val = ssm.get(f"{SSM_PREFIX}/{short}")
        if val is not None:
            env[var] = val

    db_password = env.get("DB_PASSWORD", "")
    db_host = os.environ.get("DB_HOST", "cibello-prod-db.cvi0qcksmsfj.eu-north-1.rds.amazonaws.com")
    db_name = os.environ.get("DB_NAME", "cibello")
    test_db_name = os.environ.get("TEST_DB_NAME", "cibello_test")
    db_user = os.environ.get("DB_USER", "cibello_admin")
    db_sslmode = os.environ.get("DB_SSLMODE", "require")

    if db_password:
        env["DATABASE_URL"] = f"postgres://{db_user}:{db_password}@{db_host}:5432/{db_name}?sslmode={db_sslmode}"
        env["TEST_DATABASE_URL"] = f"postgres://{db_user}:{db_password}@{db_host}:5432/{test_db_name}?sslmode={db_sslmode}"

    # Rensa temporär nyckel
    env.pop("DB_PASSWORD", None)

    return env


def write_env(env: dict[str, str], dry_run: bool = False) -> None:
    lines = [f"{k}={v}" for k, v in env.items()]
    if dry_run:
        print(f"[sync-env] DRY-RUN: skulle skriva {ENV_PATH} ({len(env)} rader)")
        return
    ENV_PATH.parent.mkdir(parents=True, exist_ok=True)
    ENV_PATH.write_text("\n".join(lines) + "\n", encoding="utf-8")
    os.chmod(ENV_PATH, 0o600)
    print(f"[sync-env] skrev {ENV_PATH} ({len(env)} rader)")


def main() -> int:
    dry_run = "--dry-run" in sys.argv
    names = [f"{SSM_PREFIX}/{short}" for short in SSM_MAP]
    ssm = get_parameters(names)
    env = build_env(ssm)
    write_env(env, dry_run=dry_run)
    return 0


if __name__ == "__main__":
    sys.exit(main())
