#!/usr/bin/env sh
set -eu

ENV_FILE="${1:-.env}"
errors=0
warnings=0

if [ ! -f "$ENV_FILE" ]; then
    echo "ERROR: env file not found: $ENV_FILE" >&2
    exit 1
fi

value() {
    key="$1"
    awk -v key="$key" '
        /^[[:space:]]*#/ || /^[[:space:]]*$/ { next }
        {
            line = $0
            sub(/\r$/, "", line)
            split(line, parts, "=")
            current = parts[1]
            gsub(/^[ \t]+|[ \t]+$/, "", current)
            if (current == key) {
                sub(/^[^=]*=/, "", line)
                gsub(/^"/, "", line)
                gsub(/"$/, "", line)
                gsub(/^'\''/, "", line)
                gsub(/'\''$/, "", line)
                print line
                exit
            }
        }
    ' "$ENV_FILE"
}

is_placeholder() {
    case "${1:-}" in
        ""|"<"*">"|*example.com*|"change-me"|"changeme"|"password"|"secret")
            return 0
            ;;
        *)
            return 1
            ;;
    esac
}

error() {
    errors=$((errors + 1))
    echo "ERROR: $1" >&2
}

warn() {
    warnings=$((warnings + 1))
    echo "WARN: $1" >&2
}

require_value() {
    key="$1"
    label="${2:-$1}"
    current="$(value "$key")"
    if is_placeholder "$current"; then
        error "$label must be set to a production value."
    fi
}

require_secret() {
    key="$1"
    current="$(value "$key")"
    if is_placeholder "$current"; then
        error "$key must be set."
        return
    fi
    case "$current" in
        admin|demo|keycloak|qsfera|qsfera-secret-key)
            error "$key uses a known demo/default value."
            return
            ;;
    esac
    if [ "${#current}" -lt 16 ]; then
        error "$key must be at least 16 characters."
    fi
}

enabled() {
    current="$(value "$1")"
    [ -n "$current" ]
}

require_value OC_DOMAIN "OC_DOMAIN"
require_value TRAEFIK_ACME_MAIL "TRAEFIK_ACME_MAIL"
require_secret ADMIN_PASSWORD

case "$(value INSECURE)" in
    true|TRUE|1|yes|YES)
        error "INSECURE must be false for production."
        ;;
esac

case "$(value DEMO_USERS)" in
    true|TRUE|1|yes|YES)
        error "DEMO_USERS must be false for production."
        ;;
esac

case "$(value OC_DOCKER_IMAGE)" in
    qsfera/qsfera)
        ;;
    "")
        warn "OC_DOCKER_IMAGE is empty; compose default must be verified before rollout."
        ;;
    *)
        error "OC_DOCKER_IMAGE must be qsfera/qsfera for production."
        ;;
esac

case "$(value OC_DOCKER_TAG)" in
    ""|latest|"<"*">")
        error "OC_DOCKER_TAG must pin a concrete production release tag."
        ;;
esac

if ! enabled QSFERA; then
    error "QSFERA=:qsfera.yml must be enabled."
fi

if enabled DECOMPOSEDS3; then
    require_value DECOMPOSEDS3_ENDPOINT "DECOMPOSEDS3_ENDPOINT"
    require_value DECOMPOSEDS3_REGION "DECOMPOSEDS3_REGION"
    require_secret DECOMPOSEDS3_ACCESS_KEY
    require_secret DECOMPOSEDS3_SECRET_KEY
    require_value DECOMPOSEDS3_BUCKET "DECOMPOSEDS3_BUCKET"
fi

if enabled DECOMPOSEDS3_MINIO; then
    error "DECOMPOSEDS3_MINIO is for test/lab installs and must not be enabled for public production."
fi

if enabled KEYCLOAK; then
    require_value KEYCLOAK_DOMAIN "KEYCLOAK_DOMAIN"
    require_value KEYCLOAK_REALM "KEYCLOAK_REALM"
    require_secret KEYCLOAK_POSTGRES_PASSWORD
    require_value KEYCLOAK_ADMIN_USER "KEYCLOAK_ADMIN_USER"
    require_secret KEYCLOAK_ADMIN_PASSWORD
fi

if [ -z "$(value OC_CONFIG_DIR)" ] || [ -z "$(value OC_DATA_DIR)" ]; then
    warn "OC_CONFIG_DIR and OC_DATA_DIR are not both set; docker volumes are harder to back up and restore."
fi

if [ "$errors" -gt 0 ]; then
    echo "Production env validation failed: $errors error(s), $warnings warning(s)." >&2
    exit 1
fi

echo "Production env validation passed: $warnings warning(s)."
