#!/usr/bin/env bash
# Simple script to set allowed email addresses for Cloudflare Access
# Usage: ./set-access-emails.sh email1@example.com email2@example.com ...

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TUNNELS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }

# Load .env
if [ -f "$TUNNELS_DIR/../../.env" ]; then
    source "$TUNNELS_DIR/../../.env" 2>/dev/null || true
fi

if [[ -z "${CLOUDFLARE_ACCOUNT_ID:-}" ]] || [[ -z "${CLOUDFLARE_API_KEY:-}" ]] || [[ -z "${CLOUDFLARE_EMAIL:-}" ]]; then
    log_error "Cloudflare credentials not found in .env"
    exit 1
fi

# Get emails from command line
ALLOWED_EMAILS=("$@")

if [ ${#ALLOWED_EMAILS[@]} -eq 0 ]; then
    log_error "Usage: $0 email1@example.com email2@example.com ..."
    echo ""
    log_info "Example:"
    echo "  $0 admin@example.com user1@example.com user2@example.com"
    exit 1
fi

log_info "Configuring Access policies for: ${ALLOWED_EMAILS[*]}"
echo ""

# App IDs (from earlier creation)
declare -A APP_IDS=(
    ["ml110-01.d-bis.org"]="ebc7cafa-11dc-4bfa-8347-4e6c229f4d3b"
    ["r630-01.d-bis.org"]="967625a2-0199-490a-9f4f-2de5c8d49243"
    ["r630-02.d-bis.org"]="618ab003-37bf-413e-b0fa-13963c2186c5"
)

# Function to make API request
cf_api_request() {
    local method="$1"
    local endpoint="$2"
    local data="${3:-}"
    
    local url="https://api.cloudflare.com/client/v4${endpoint}"
    local temp_file=$(mktemp)
    local http_code
    
    if [[ -n "$data" ]]; then
        http_code=$(curl -s -o "$temp_file" -w "%{http_code}" \
            -X "$method" "$url" \
            -H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
            -H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
            -H "Content-Type: application/json" \
            -d "$data" 2>/dev/null)
    else
        http_code=$(curl -s -o "$temp_file" -w "%{http_code}" \
            -X "$method" "$url" \
            -H "X-Auth-Email: ${CLOUDFLARE_EMAIL}" \
            -H "X-Auth-Key: ${CLOUDFLARE_API_KEY}" \
            -H "Content-Type: application/json" 2>/dev/null)
    fi
    
    local response=$(cat "$temp_file" 2>/dev/null || echo "")
    rm -f "$temp_file"
    
    if [[ "$http_code" != "200" ]] && [[ "$http_code" != "201" ]]; then
        return 1
    fi
    
    echo "$response"
}

# Build email includes
EMAIL_INCLUDES=$(printf '%s\n' "${ALLOWED_EMAILS[@]}" | jq -R . | jq -s . | jq 'map({email: {email: .}})')

# Configure each app
for hostname in "${!APP_IDS[@]}"; do
    app_id="${APP_IDS[$hostname]}"
    
    log_info "Configuring $hostname..."
    
    # Get existing policies
    POLICIES=$(cf_api_request "GET" "/accounts/${CLOUDFLARE_ACCOUNT_ID}/access/apps/${app_id}/policies" 2>&1) || POLICIES="{}"
    EXISTING_ID=$(echo "$POLICIES" | jq -r '.result[]? | select(.name == "Allow Team Access") | .id' 2>/dev/null || echo "")
    
    # Build policy (require field removed - email verification is default)
    POLICY_DATA=$(jq -n \
        --argjson emails "$EMAIL_INCLUDES" \
        '{
            name: "Allow Team Access",
            decision: "allow",
            include: $emails
        }')
    
    if [[ -n "$EXISTING_ID" ]] && [[ "$EXISTING_ID" != "null" ]]; then
        # Update
        response=$(cf_api_request "PUT" "/accounts/${CLOUDFLARE_ACCOUNT_ID}/access/apps/${app_id}/policies/${EXISTING_ID}" "$POLICY_DATA" 2>&1)
    else
        # Create
        response=$(cf_api_request "POST" "/accounts/${CLOUDFLARE_ACCOUNT_ID}/access/apps/${app_id}/policies" "$POLICY_DATA" 2>&1)
    fi
    
    if echo "$response" | jq -e '.success' >/dev/null 2>&1; then
        log_success "  ✓ $hostname configured"
    else
        log_error "  ✗ Failed for $hostname"
        echo "$response" | jq -r '.errors[0].message // "Unknown error"' 2>/dev/null || echo "$response" | head -3
    fi
done

echo ""
log_success "=== Access Policies Configured ==="
log_info "Allowed emails:"
for email in "${ALLOWED_EMAILS[@]}"; do
    echo "  - $email"
done

