#!/bin/bash
#
# Local Orchestrator Bootstrap (with License Validation)
#
# This script runs AFTER docker-compose up to:
# 1. VALIDATE LICENSE with LetsBe Hub (REQUIRED for official installations)
# 2. Wait for orchestrator health check (includes migrations via container startup)
# 3. Get local tenant ID (for verification/logging)
# 4. Write simplified credentials file
#
# NOTE: Database migrations are now run by the orchestrator container on startup
#
# IMPORTANT: Agent registration is handled via LOCAL_AGENT_KEY
# from docker-compose.yml environment, NOT registration tokens.
#
# This script is idempotent - safe to run multiple times.
#
# Usage:
#   HUB_URL="https://hub.letsbe.biz" \
#   LICENSE_KEY="lb_inst_..." \
#   INSTANCE_ID="acme-orchestrator" \
#   ADMIN_API_KEY="admin_key" \
#   CUSTOMER="acme" \
#   bash local_bootstrap.sh

set -euo pipefail

# ============ CONFIGURATION ============

HUB_URL="${HUB_URL:-https://hub.letsbe.biz}"
LICENSE_KEY="${LICENSE_KEY:-}"
INSTANCE_ID="${INSTANCE_ID:?INSTANCE_ID required}"
ORCHESTRATOR_URL="${ORCHESTRATOR_URL:-http://localhost:8100}"
ADMIN_API_KEY="${ADMIN_API_KEY:?ADMIN_API_KEY required}"
CUSTOMER="${CUSTOMER:?CUSTOMER required}"
CREDENTIALS_DIR="${CREDENTIALS_DIR:-/opt/letsbe/env}"

# ============ LOGGING ============

log_info() { echo "[BOOTSTRAP] $(date '+%Y-%m-%d %H:%M:%S') $*"; }
log_error() { echo "[BOOTSTRAP-ERROR] $(date '+%Y-%m-%d %H:%M:%S') $*" >&2; }
log_success() { echo "[BOOTSTRAP-OK] $(date '+%Y-%m-%d %H:%M:%S') $*"; }
log_warn() { echo "[BOOTSTRAP-WARN] $(date '+%Y-%m-%d %H:%M:%S') $*" >&2; }

# ============ LICENSE VALIDATION (FIRST STEP) ============

validate_license() {
    log_info "Validating license with LetsBe Hub..."

    # Check if license key is provided
    if [ -z "$LICENSE_KEY" ]; then
        log_error "LICENSE_KEY is required but not provided."
        log_error "Please obtain a license key from LetsBe Hub."
        log_error "Add 'license_key' to your config.json and re-run provisioning."
        exit 1
    fi

    # Check if Hub URL is configured
    if [ -z "$HUB_URL" ]; then
        log_error "HUB_URL is required but not provided."
        exit 1
    fi

    # Call Hub activation endpoint
    local http_code
    http_code=$(curl -s -o /tmp/activation_response.json -w "%{http_code}" \
        -X POST "${HUB_URL}/api/v1/instances/activate" \
        -H "Content-Type: application/json" \
        -d "{\"license_key\": \"${LICENSE_KEY}\", \"instance_id\": \"${INSTANCE_ID}\"}")

    if [ "$http_code" != "200" ]; then
        log_error "License validation failed (HTTP $http_code)"

        # Parse error response
        if [ -f /tmp/activation_response.json ]; then
            local error_msg
            local error_code

            # Try to parse JSON error response
            error_msg=$(jq -r '.error // .detail.error // "Unknown error"' /tmp/activation_response.json 2>/dev/null || echo "Unknown error")
            error_code=$(jq -r '.code // .detail.code // "unknown"' /tmp/activation_response.json 2>/dev/null || echo "unknown")

            log_error "Error: $error_msg (code: $error_code)"

            case "$error_code" in
                "invalid_license")
                    log_error "The provided license key is invalid."
                    log_error "Please verify your license_key in config.json."
                    ;;
                "expired")
                    log_error "Your license has expired."
                    log_error "Please contact LetsBe to renew your license."
                    ;;
                "suspended")
                    log_error "Your license has been suspended."
                    log_error "Please contact LetsBe support."
                    ;;
                "instance_not_found")
                    log_error "Instance ID '$INSTANCE_ID' not found in Hub."
                    log_error "Please ensure your instance was created in LetsBe Hub."
                    ;;
                *)
                    log_error "Please contact LetsBe support with error code: $error_code"
                    ;;
            esac
        fi

        rm -f /tmp/activation_response.json
        exit 1
    fi

    log_success "License validated successfully!"

    # Extract hub_api_key from response if provided
    local hub_api_key
    hub_api_key=$(jq -r '.hub_api_key // empty' /tmp/activation_response.json 2>/dev/null || echo "")

    if [ -n "$hub_api_key" ] && [ "$hub_api_key" != "USE_EXISTING" ]; then
        log_info "Received hub_api_key from activation"
        export HUB_API_KEY="$hub_api_key"

        # Save to credentials file
        mkdir -p "${CREDENTIALS_DIR}"
        echo "HUB_API_KEY=${hub_api_key}" >> "${CREDENTIALS_DIR}/hub-credentials.env"
        chmod 600 "${CREDENTIALS_DIR}/hub-credentials.env"
        log_info "Hub API key saved to ${CREDENTIALS_DIR}/hub-credentials.env"
    fi

    rm -f /tmp/activation_response.json
}

# ============ ORCHESTRATOR FUNCTIONS ============

wait_for_orchestrator() {
    log_info "Waiting for orchestrator to be ready..."
    local max_attempts=60
    local attempt=0

    while [[ $attempt -lt $max_attempts ]]; do
        if curl -sf "${ORCHESTRATOR_URL}/health" > /dev/null 2>&1; then
            log_success "Orchestrator is ready"
            return 0
        fi
        attempt=$((attempt + 1))
        log_info "Attempt $attempt/$max_attempts - waiting..."
        sleep 2
    done

    log_error "Orchestrator not ready after ${max_attempts} attempts"
    return 1
}

run_migrations() {
    log_info "Running database migrations..."

    # Find the orchestrator container
    local orchestrator_container
    orchestrator_container=$(docker ps --format '{{.Names}}' | grep -E "(orchestrator|${CUSTOMER}.*orchestrator)" | head -1)

    if [ -z "$orchestrator_container" ]; then
        log_error "Could not find orchestrator container"
        return 1
    fi

    docker exec "$orchestrator_container" alembic upgrade head
    log_success "Migrations complete"
}

get_local_tenant_id() {
    log_info "Getting local tenant ID..."
    local response
    response=$(curl -sf "${ORCHESTRATOR_URL}/api/v1/meta/instance")
    local tenant_id
    tenant_id=$(echo "$response" | jq -r '.tenant_id')

    if [ "$tenant_id" == "null" ] || [ -z "$tenant_id" ]; then
        log_error "Failed to get tenant_id from /api/v1/meta/instance"
        log_error "Response: $response"
        return 1
    fi

    log_success "Tenant ID: $tenant_id"
    echo "$tenant_id"
}

write_credentials() {
    local tenant_id=$1
    local credentials_file="${CREDENTIALS_DIR}/sysadmin-credentials.env"

    log_info "Writing credentials to ${credentials_file}..."

    mkdir -p "${CREDENTIALS_DIR}"

    # NOTE: In LOCAL_MODE, agent uses LOCAL_AGENT_KEY from docker-compose.yml
    # We do NOT write ADMIN_API_KEY here - agent doesn't need it
    # We do NOT write registration tokens - LOCAL_MODE uses direct key auth
    cat > "${credentials_file}" <<EOF
# LetsBe LOCAL_MODE Credentials
# Generated by local_bootstrap.sh at $(date -u '+%Y-%m-%dT%H:%M:%SZ')
#
# Agent Registration: Uses LOCAL_AGENT_KEY from docker-compose.yml
# NOT stored here to minimize secrets at rest
TENANT_ID=${tenant_id}
INSTANCE_ID=${INSTANCE_ID}
EOF

    chmod 600 "${credentials_file}"
    log_success "Credentials written"
}

write_admin_credentials() {
    # Separate file for admin scripts only - NOT for agent
    local admin_creds="${CREDENTIALS_DIR}/admin-credentials.env"

    log_info "Writing admin credentials to ${admin_creds}..."

    mkdir -p "${CREDENTIALS_DIR}"
    cat > "${admin_creds}" <<EOF
# LetsBe Admin Credentials (root only)
# Generated by local_bootstrap.sh at $(date -u '+%Y-%m-%dT%H:%M:%SZ')
ADMIN_API_KEY=${ADMIN_API_KEY}
EOF

    chmod 600 "${admin_creds}"
    chown root:root "${admin_creds}" 2>/dev/null || true
    log_success "Admin credentials written (root-only access)"
}

# ============ MAIN ============

main() {
    log_info "Starting local orchestrator bootstrap for: ${CUSTOMER}"
    log_info "Instance ID: ${INSTANCE_ID}"

    # STEP 1: License validation (REQUIRED for official installations)
    # This is the gating step - if license fails, nothing else runs
    validate_license

    # STEP 2: Wait for orchestrator (migrations run on container startup)
    wait_for_orchestrator

    # STEP 3: Get tenant ID (for verification)
    local tenant_id
    tenant_id=$(get_local_tenant_id)

    # STEP 4: Write credentials
    # NOTE: No registration token creation - LOCAL_MODE uses LOCAL_AGENT_KEY
    write_credentials "${tenant_id}"
    write_admin_credentials

    log_success "Bootstrap complete!"
    log_info "Instance '${INSTANCE_ID}' is now licensed and activated"
    log_info ""
    log_info "Agent registration: Uses LOCAL_AGENT_KEY from docker-compose.yml"
    log_info "Agent should register with orchestrator within 30 seconds"
}

main "$@"
