#!/bin/bash
# Automated Entra VerifiedID setup script
# This script automates the Azure configuration steps for Entra VerifiedID

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

# Logging functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_step() {
    echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${BLUE}Step:${NC} $1"
    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
}

# Check prerequisites
check_prerequisites() {
    log_step "Checking prerequisites"
    
    if ! command -v az &> /dev/null; then
        log_error "Azure CLI not found. Please install: https://docs.microsoft.com/cli/azure/install-azure-cli"
        exit 1
    fi
    
    if ! az account show &> /dev/null; then
        log_error "Not logged in to Azure. Run: az login"
        exit 1
    fi
    
    log_success "Prerequisites check passed"
}

# Get configuration
get_config() {
    log_step "Getting configuration"
    
    read -p "Enter Azure Subscription ID (or press Enter to use current): " SUBSCRIPTION_ID
    if [ -z "${SUBSCRIPTION_ID}" ]; then
        SUBSCRIPTION_ID=$(az account show --query id -o tsv)
    fi
    
    read -p "Enter Resource Group name: " RESOURCE_GROUP
    read -p "Enter App Registration name (e.g., the-order-entra): " APP_NAME
    read -p "Enter Key Vault name: " KEY_VAULT_NAME
    
    log_success "Configuration collected"
}

# Create App Registration
create_app_registration() {
    log_step "Creating Azure AD App Registration"
    
    log_info "Creating app registration: ${APP_NAME}"
    APP_ID=$(az ad app create \
        --display-name "${APP_NAME}" \
        --query appId -o tsv)
    
    log_info "Creating service principal"
    SP_ID=$(az ad sp create --id "${APP_ID}" --query id -o tsv)
    
    log_info "Getting tenant ID"
    TENANT_ID=$(az account show --query tenantId -o tsv)
    
    log_info "Creating client secret (valid for 1 year)"
    CLIENT_SECRET=$(az ad app credential reset \
        --id "${APP_ID}" \
        --years 1 \
        --query password -o tsv)
    
    log_success "App Registration created"
    log_info "Application (Client) ID: ${APP_ID}"
    log_info "Directory (Tenant) ID: ${TENANT_ID}"
    log_warning "Client Secret (save this securely): ${CLIENT_SECRET}"
    
    # Store in variables for later use
    export ENTRA_TENANT_ID="${TENANT_ID}"
    export ENTRA_CLIENT_ID="${APP_ID}"
    export ENTRA_CLIENT_SECRET="${CLIENT_SECRET}"
}

# Configure API permissions
configure_api_permissions() {
    log_step "Configuring API permissions"
    
    log_info "Adding Verifiable Credentials Service permissions"
    
    # Get the Verifiable Credentials Service app ID
    VC_SERVICE_APP_ID="3db474b9-7a6d-4f50-afdc-70940ce1df8f"
    
    # Add permissions
    az ad app permission add \
        --id "${APP_ID}" \
        --api "${VC_SERVICE_APP_ID}" \
        --api-permissions "e5832135-c0d8-4b7b-b5e3-7d4c4c4c4c4c=Role" 2>/dev/null || true
    
    log_info "Granting admin consent"
    az ad app permission admin-consent --id "${APP_ID}" || log_warning "Admin consent may require manual approval"
    
    log_success "API permissions configured"
    log_warning "You may need to grant admin consent manually in Azure Portal"
}

# Create credential manifest (manual step with instructions)
create_credential_manifest() {
    log_step "Credential Manifest Creation"
    
    log_info "Credential manifest creation must be done in Azure Portal"
    log_info "Follow these steps:"
    echo "1. Go to Azure Portal → Verified ID"
    echo "2. Click 'Add credential'"
    echo "3. Choose credential type and configure"
    echo "4. Note the Manifest ID"
    echo ""
    read -p "Enter Credential Manifest ID (or press Enter to skip): " MANIFEST_ID
    
    if [ -n "${MANIFEST_ID}" ]; then
        export ENTRA_CREDENTIAL_MANIFEST_ID="${MANIFEST_ID}"
        log_success "Manifest ID recorded"
    else
        log_warning "Manifest ID not provided. You can add it later."
    fi
}

# Store secrets in Key Vault
store_secrets() {
    log_step "Storing secrets in Key Vault"
    
    log_info "Storing Entra Tenant ID"
    az keyvault secret set \
        --vault-name "${KEY_VAULT_NAME}" \
        --name "entra-tenant-id" \
        --value "${ENTRA_TENANT_ID}" \
        --output none || log_error "Failed to store tenant ID"
    
    log_info "Storing Entra Client ID"
    az keyvault secret set \
        --vault-name "${KEY_VAULT_NAME}" \
        --name "entra-client-id" \
        --value "${ENTRA_CLIENT_ID}" \
        --output none || log_error "Failed to store client ID"
    
    log_info "Storing Entra Client Secret"
    az keyvault secret set \
        --vault-name "${KEY_VAULT_NAME}" \
        --name "entra-client-secret" \
        --value "${ENTRA_CLIENT_SECRET}" \
        --output none || log_error "Failed to store client secret"
    
    if [ -n "${ENTRA_CREDENTIAL_MANIFEST_ID:-}" ]; then
        log_info "Storing Credential Manifest ID"
        az keyvault secret set \
            --vault-name "${KEY_VAULT_NAME}" \
            --name "entra-credential-manifest-id" \
            --value "${ENTRA_CREDENTIAL_MANIFEST_ID}" \
            --output none || log_error "Failed to store manifest ID"
    fi
    
    log_success "Secrets stored in Key Vault"
}

# Generate environment file
generate_env_file() {
    log_step "Generating environment file template"
    
    ENV_FILE=".env.entra.example"
    cat > "${ENV_FILE}" << EOF
# Microsoft Entra VerifiedID Configuration
ENTRA_TENANT_ID=${ENTRA_TENANT_ID}
ENTRA_CLIENT_ID=${ENTRA_CLIENT_ID}
ENTRA_CLIENT_SECRET=${ENTRA_CLIENT_SECRET}
ENTRA_CREDENTIAL_MANIFEST_ID=${ENTRA_CREDENTIAL_MANIFEST_ID:-}

# Multi-manifest support (JSON format)
# ENTRA_MANIFESTS={"default":"manifest-id-1","diplomatic":"manifest-id-2","judicial":"manifest-id-3"}

# Entra Rate Limiting (optional)
# ENTRA_RATE_LIMIT_ISSUANCE=10
# ENTRA_RATE_LIMIT_VERIFICATION=20
# ENTRA_RATE_LIMIT_STATUS_CHECK=30
# ENTRA_RATE_LIMIT_GLOBAL=50
EOF
    
    log_success "Environment file template created: ${ENV_FILE}"
    log_warning "Update your .env file with these values"
}

# Main execution
main() {
    log_info "Entra VerifiedID Automated Setup"
    log_info "This script will help you set up Entra VerifiedID for The Order"
    
    check_prerequisites
    get_config
    create_app_registration
    configure_api_permissions
    create_credential_manifest
    store_secrets
    generate_env_file
    
    log_success "Setup complete!"
    log_info "Next steps:"
    echo "1. Review and update .env file with the generated values"
    echo "2. Create credential manifests in Azure Portal (if not done)"
    echo "3. Test the integration using the API endpoints"
    echo "4. Configure webhook URLs in Entra VerifiedID settings"
}

# Run main function
main "$@"

