#!/bin/bash
# =============================================================================
# WOOO AIOps - Credential escrow verification marker
# 2026-05-06 ogt + Codex: 建立不含 secret 的人工金庫覆核 marker。
#
# 這個腳本不讀、不寫、不列印任何 credential。它只在人工確認密碼管理器
# 或離線加密金庫可用後，寫入 timestamp / item / evidence_id。
# =============================================================================

set -euo pipefail

# This helper is often used to print copy/paste-safe operator commands.
# Keep the shared library startup banner quiet by default; real marker writes
# still emit their explicit success line below.
export BACKUP_COMMON_QUIET="${BACKUP_COMMON_QUIET:-1}"
source "$(dirname "$0")/common.sh"

ESCROW_DIR="${BACKUP_BASE}/escrow-evidence"
BACKUP_HEALTH_EXPORTER="${BACKUP_HEALTH_EXPORTER:-/home/wooo/scripts/backup-health-textfile-exporter.py}"
BACKUP_HEALTH_TEXTFILE_DIR="${BACKUP_HEALTH_TEXTFILE_DIR:-/home/wooo/node_exporter_textfiles}"
TEXTFILE_REFRESH_ENABLED="${TEXTFILE_REFRESH_ENABLED:-1}"
ITEM=""
EVIDENCE_ID=""
NOTE=""
MODE="write"
DRY_RUN=0

ALLOWED_ITEMS=(
    "restic_repository_password"
    "offsite_provider_credentials"
    "break_glass_admin_credentials"
    "dns_registrar_recovery"
    "oauth_ai_provider_recovery"
)

usage() {
    cat <<'USAGE'
Usage:
  mark-credential-escrow-verified.sh --item <item> --evidence-id <id> [--note <short-note>]
  mark-credential-escrow-verified.sh --item <item> --evidence-id <id> --dry-run
  mark-credential-escrow-verified.sh --status
  mark-credential-escrow-verified.sh --missing-commands

Allowed items:
  restic_repository_password
  offsite_provider_credentials
  break_glass_admin_credentials
  dns_registrar_recovery
  oauth_ai_provider_recovery

Rules:
  - evidence-id must be a non-secret reference such as a vault item id, ticket id,
    sealed envelope id, or recovery checklist id.
  - Do not pass passwords, tokens, recovery codes, or secret URLs.
  - Placeholder values such as EVIDENCE_ID_FOR_* or VAULT-ITEM-ID are rejected.
USAGE
}

is_allowed_item() {
    local item="$1"
    for allowed in "${ALLOWED_ITEMS[@]}"; do
        [ "${item}" = "${allowed}" ] && return 0
    done
    return 1
}

reject_suspicious_value() {
    local label="$1"
    local value="$2"
    if [ "${#value}" -gt 160 ]; then
        echo "${label} 太長；只允許短 evidence id，不允許 secret material" >&2
        return 1
    fi
    if grep -Eq '(BEGIN |PRIVATE KEY|[A-Za-z0-9+/]{40,}={0,2})' <<<"${value}" \
        || grep -Eiq '(password|token|secret)[[:space:]]*[:=]' <<<"${value}"; then
        echo "${label} 看起來可能含 secret；拒絕寫入 marker" >&2
        return 1
    fi
    if grep -Eiq '^(EVIDENCE_ID_FOR_|VAULT-ITEM-ID$|TODO$|TBD$|CHANGE_ME$|CHANGEME$|REPLACE_ME$|EXAMPLE)' <<<"${value}"; then
        echo "${label} 是 placeholder；請換成真實、非 secret 的證據 ID" >&2
        return 1
    fi
    if grep -Eiq 'https?://|ssh://|file://' <<<"${value}"; then
        echo "${label} 看起來像 URL；請改用不含 secret 的短 evidence id" >&2
        return 1
    fi
    return 0
}

status() {
    install -d -m 750 "${ESCROW_DIR}"
    for item in "${ALLOWED_ITEMS[@]}"; do
        local path="${ESCROW_DIR}/${item}.last_verified"
        if [ -f "${path}" ]; then
            printf '%s present ' "${item}"
            sed -n 's/^timestamp=//p;s/^evidence_id=/evidence_id=/p' "${path}" | tr '\n' ' '
            printf '\n'
        else
            printf '%s missing\n' "${item}"
        fi
    done
}

print_missing_commands() {
    install -d -m 750 "${ESCROW_DIR}"
    local missing=0
    for item in "${ALLOWED_ITEMS[@]}"; do
        local path="${ESCROW_DIR}/${item}.last_verified"
        [ -f "${path}" ] && continue
        missing=$((missing + 1))
        cat <<EOF
/backup/scripts/mark-credential-escrow-verified.sh --item ${item} --evidence-id EVIDENCE_ID_FOR_${item}
EOF
    done
    if [ "${missing}" -eq 0 ]; then
        echo "ALL_ESCROW_MARKERS_PRESENT=1"
    else
        echo "MISSING_ESCROW_MARKER_COUNT=${missing}"
    fi
}

refresh_backup_health_textfile() {
    [ "${TEXTFILE_REFRESH_ENABLED}" = "1" ] || {
        echo "TEXTFILE_REFRESH_SKIPPED disabled"
        return 0
    }
    [ -x "${BACKUP_HEALTH_EXPORTER}" ] || {
        echo "TEXTFILE_REFRESH_SKIPPED exporter_missing=${BACKUP_HEALTH_EXPORTER}"
        return 0
    }

    if AIOPS_HOST_LABEL=110 \
        NODE_EXPORTER_TEXTFILE_DIR="${BACKUP_HEALTH_TEXTFILE_DIR}" \
        AIOPS_BACKUP_COMMON_SH="${BACKUP_BASE}/scripts/common.sh" \
        AIOPS_BACKUP_OFFSITE_ENV="${BACKUP_BASE}/scripts/offsite.env" \
        AIOPS_OFFSITE_STATUS_DIR="${BACKUP_BASE}/offsite" \
        AIOPS_ESCROW_EVIDENCE_DIR="${ESCROW_DIR}" \
        "${BACKUP_HEALTH_EXPORTER}" >/dev/null 2>&1; then
        echo "TEXTFILE_REFRESHED ${BACKUP_HEALTH_TEXTFILE_DIR}/backup_health.prom"
        return 0
    fi

    echo "TEXTFILE_REFRESH_FAILED exporter=${BACKUP_HEALTH_EXPORTER}" >&2
    return 0
}

while [ "$#" -gt 0 ]; do
    case "$1" in
        --item)
            ITEM="${2:-}"
            shift 2
            ;;
        --evidence-id)
            EVIDENCE_ID="${2:-}"
            shift 2
            ;;
        --note)
            NOTE="${2:-}"
            shift 2
            ;;
        --dry-run)
            DRY_RUN=1
            shift
            ;;
        --status)
            status
            exit 0
            ;;
        --missing-commands)
            MODE="missing-commands"
            shift
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            echo "Unknown argument: $1" >&2
            usage >&2
            exit 2
            ;;
    esac
done

if [ "${MODE}" = "missing-commands" ]; then
    print_missing_commands
    exit 0
fi

if [ -z "${ITEM}" ] || [ -z "${EVIDENCE_ID}" ]; then
    usage >&2
    exit 2
fi

if ! is_allowed_item "${ITEM}"; then
    echo "不允許的 escrow item: ${ITEM}" >&2
    usage >&2
    exit 2
fi

reject_suspicious_value "evidence-id" "${EVIDENCE_ID}"
[ -n "${NOTE}" ] && reject_suspicious_value "note" "${NOTE}"

marker="${ESCROW_DIR}/${ITEM}.last_verified"
timestamp="$(date +%s)"

if [ "${DRY_RUN}" = "1" ]; then
    echo "DRY_RUN=1"
    echo "MARKER_WOULD_WRITE ${marker}"
    echo "ITEM=${ITEM}"
    echo "EVIDENCE_ID_ACCEPTED=1"
    exit 0
fi

install -d -m 750 "${ESCROW_DIR}"

cat > "${marker}" <<EOF
timestamp=${timestamp}
item=${ITEM}
operator=$(whoami)
evidence_id=${EVIDENCE_ID}
note=${NOTE}
EOF
chmod 0640 "${marker}"

log_success "Credential escrow marker 已更新: ${ITEM}"
echo "MARKER_WRITTEN ${marker}"
refresh_backup_health_textfile
