#!/usr/bin/env bash
# Decrypts ansible/group_vars/vault.yml and checks all required secrets are present
# and non-empty, and validates optional secrets when they are present.
# Exits non-zero if any check fails.
# Usage: bash scripts/check-vault.sh

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VAULT_FILE="${REPO_ROOT}/ansible/group_vars/all/vault.yml"

if [ ! -f "${VAULT_FILE}" ]; then
  echo "ERROR: vault file not found at ${VAULT_FILE}" >&2
  echo "       Create it with: ansible-vault create ansible/group_vars/all/vault.yml" >&2
  exit 1
fi

if ! command -v ansible-vault &>/dev/null; then
  echo "ERROR: ansible-vault not found — install with: pip install ansible" >&2
  exit 1
fi

echo "==> Decrypting vault (you will be prompted for the vault password)"
VAULT_CONTENT=$(ansible-vault view "${VAULT_FILE}")

# Pass vault content via environment variable — avoids a pipe+heredoc stdin conflict
# where python3 - consumes stdin for the script, leaving sys.stdin.read() empty.
export VAULT_CONTENT
python3 - <<'PYEOF'
import os, sys, yaml

data = yaml.safe_load(os.environ['VAULT_CONTENT'])

# Required non-empty scalar strings
required_scalars = [
    "gitea_db_password",
    "gitea_secret_key",
    "gitea_internal_token",
    "keycloak_db_password",
    "keycloak_admin_password",
    "nextcloud_db_password",
    "nextcloud_admin_password",
    "roundcube_db_password",
    "roundcube_des_key",
    "vaultwarden_admin_token",
]

# Required non-empty lists (must contain at least one entry)
required_lists = [
    "traefik_dashboard_users",
    "registry_users",
    "dovecot_users",
]

# Optional scalars: validated only when present — (key, validator_fn, hint)
SSH_KEY_PREFIXES = ("ssh-rsa", "ssh-ed25519", "ssh-ecdsa", "ecdsa-sha2-", "sk-ssh-")

def is_nonempty(val):
    return bool(str(val).strip())

def is_ssh_pubkey(val):
    return any(str(val).strip().startswith(p) for p in SSH_KEY_PREFIXES)

optional_scalars = [
    ("vaultwarden_sso_client_secret", is_nonempty,  "must be a non-empty string"),
    ("dl_sftp_authorized_keys",       is_ssh_pubkey, "must be a valid SSH public key (ssh-ed25519 / ssh-rsa / ecdsa-sha2-*)"),
]

errors = []

for key in required_scalars:
    val = data.get(key, "")
    if not val or str(val).strip() in ("", '""', "''"):
        errors.append(f"{key}: missing or empty (required)")

for key in required_lists:
    val = data.get(key)
    if not isinstance(val, list) or len(val) == 0:
        errors.append(f"{key}: missing or empty list (required)")

for key, validator, hint in optional_scalars:
    if key in data:
        val = data[key]
        if not val or not validator(str(val).strip()):
            errors.append(f"{key}: present but invalid — {hint}")

if errors:
    print("", file=sys.stderr)
    print("ERROR: vault.yml has the following issues:", file=sys.stderr)
    for msg in errors:
        print(f"       - {msg}", file=sys.stderr)
    print("", file=sys.stderr)
    print("Edit the vault with: ansible-vault edit ansible/group_vars/all/vault.yml", file=sys.stderr)
    sys.exit(1)

print("    OK — all secrets are present and valid")
PYEOF
