#!/bin/bash
# Setup Vault OIDC Authentication

set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Load environment variables
if [ -f "infra/compose/.env" ]; then
    source "infra/compose/.env"
fi

DOMAIN=${DOMAIN:-local.lan}
VAULT_ADDR="http://localhost:8200"
AUTHENTIK_URL="https://auth.${DOMAIN}"

echo -e "${BLUE}🔧 Setting up Vault OIDC Authentication...${NC}"

# Function to check if Vault is ready
wait_for_vault() {
    echo -e "${YELLOW}⏳ Waiting for Vault to be ready...${NC}"
    local max_attempts=30
    local attempt=1

    while [ $attempt -le $max_attempts ]; do
        if docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault status > /dev/null 2>&1; then
            echo -e "${GREEN}✅ Vault is ready!${NC}"
            return 0
        fi
        echo -n "."
        sleep 2
        attempt=$((attempt + 1))
    done

    echo -e "${RED}❌ Vault failed to start${NC}"
    return 1
}

# Main setup function
setup_vault() {
    # Check if we have the root token
    if [ -z "${VAULT_DEV_ROOT_TOKEN_ID:-}" ]; then
        echo -e "${RED}❌ VAULT_DEV_ROOT_TOKEN_ID not found in environment${NC}"
        return 1
    fi

    # Check if we have the client secret
    if [ -z "${AUTHENTIK_VAULT_CLIENT_SECRET:-}" ]; then
        echo -e "${RED}❌ AUTHENTIK_VAULT_CLIENT_SECRET not found in environment${NC}"
        return 1
    fi

    # Execute commands inside the Vault container
    echo -e "${YELLOW}🔐 Configuring Vault OIDC...${NC}"

    # Login
    docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault login "$VAULT_DEV_ROOT_TOKEN_ID" > /dev/null

    # Enable OIDC auth method (ignore error if already enabled)
    docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault auth enable oidc 2>/dev/null || true
    echo -e "${GREEN}✅ OIDC auth enabled${NC}"

    # Configure OIDC
    # Note: We use the internal Docker network URL for discovery if possible, or the public one if Vault can resolve it.
    # Since Vault is in the backend network, it can reach 'apa-authentik-server'.
    # However, the discovery URL usually needs to match what the user sees (issuer validation).
    # Authentik's issuer is usually the slug URL.

    # Using the public URL for discovery URL as per standard OIDC validation
    # We might need to ensure Vault container can resolve auth.local.lan to the Traefik IP or Authentik IP.
    # In our setup, auth.local.lan resolves to 127.0.0.1 on host. Inside container, it needs to resolve to the gateway or authentik.
    # For now, let's try using the public URL. If it fails, we might need to add a host alias to the Vault container.

    docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault write auth/oidc/config \
        oidc_discovery_url="$AUTHENTIK_URL/application/o/vault-oidc/" \
        oidc_client_id="vault" \
        oidc_client_secret="$AUTHENTIK_VAULT_CLIENT_SECRET" \
        default_role="reader" \
        bound_issuer="localhost" \
        oidc_discovery_ca_pem=@/certs/local.crt

    echo -e "${GREEN}✅ OIDC config written${NC}"

    # Create reader role
    docker exec -e VAULT_ADDR=http://127.0.0.1:8200 apa-vault vault write auth/oidc/role/reader \
        bound_audiences="vault" \
        allowed_redirect_uris="https://vault.${DOMAIN}/ui/vault/auth/oidc/oidc/callback,https://vault.${DOMAIN}/oidc/callback,http://localhost:8250/oidc/callback" \
        oidc_scopes="openid,email,profile" \
        user_claim="email" \
        policies="default" \
        ttl="1h"

    echo -e "${GREEN}✅ OIDC role 'reader' created${NC}"
    echo
    echo -e "${GREEN}🎉 Vault OIDC setup complete!${NC}"
    echo -e "   Login at: ${BLUE}https://vault.${DOMAIN}/ui/vault/auth/oidc/oidc/callback${NC}"
}

# Run
wait_for_vault
setup_vault
