#!/usr/bin/env bash
# Populate .env file with Azure and Cloudflare values
# This script retrieves values from Azure CLI and prompts for Cloudflare values

set -euo pipefail


# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
SCRIPT_NAME="populate-env.sh"
SCRIPT_DESC="Populate .env with Azure & Cloudflare values; prompts and checks prerequisites"
SCRIPT_USAGE="${SCRIPT_NAME} [--help]"
SCRIPT_OPTIONS="--help             Show help"
SCRIPT_REQUIREMENTS="Azure CLI (ensure_azure_cli), permissions to write .env"
handle_help "${1:-}"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then
  # shellcheck disable=SC1090
  source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
  load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}"
elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$PROJECT_ROOT/.env"
  set +a
elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$REPO_ROOT/.env"
  set +a
fi
ENV_FILE="${PROJECT_ROOT}/.env"

# Logging functions
log() {
    log_success "[INFO] $1"
}

error() {
    log_error "[ERROR] $1"
    exit 1
}

warn() {
    log_warn "[WARNING] $1"
}

info() {
    log_info "[INFO] $1"
}

prompt() {
    log_info "[PROMPT] $1"
}

# Check if Azure CLI is installed
check_azure_cli() {
    if ! command -v az &> /dev/null; then
        error "Azure CLI is not installed. Please install it first."
        error "Installation: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash"
        exit 1
    fi
    log "Azure CLI is installed"
}

# Check if user is logged in to Azure
check_azure_login() {
    if ! az account show &> /dev/null; then
        error "Not logged in to Azure. Please run 'az login' first."
        error "Or use: ./scripts/deployment/azure-login.sh"
        exit 1
    fi
    log "Azure authentication verified"
}

# Get Azure subscription ID
get_azure_subscription_id() {
    local sub_id=$(az account show --query id -o tsv 2>/dev/null || echo "")
    if [ -z "$sub_id" ]; then
        warn "Could not get Azure subscription ID. You may need to login."
        return 1
    fi
    echo "$sub_id"
}

# Get Azure tenant ID
get_azure_tenant_id() {
    local tenant_id=$(az account show --query tenantId -o tsv 2>/dev/null || echo "")
    if [ -z "$tenant_id" ]; then
        warn "Could not get Azure tenant ID."
        return 1
    fi
    echo "$tenant_id"
}

# Get Azure resource group (if exists)
get_azure_resource_group() {
    local rg="${AZURE_RESOURCE_GROUP:-defi-oracle-mainnet-rg}"
    
    # Check if resource group exists
    if az group show --name "$rg" &> /dev/null; then
        echo "$rg"
        return 0
    fi
    
    # Try to find any resource group with "defi-oracle" in the name
    local found_rg=$(az group list --query "[?contains(name, 'defi-oracle')].name" -o tsv 2>/dev/null | head -n 1 || echo "")
    
    if [ -n "$found_rg" ]; then
        echo "$found_rg"
        return 0
    fi
    
    # Return default
    echo "$rg"
}

# Get or create Terraform backend storage account
get_terraform_backend_info() {
    local tfstate_rg="${ARM_RESOURCE_GROUP_NAME:-tfstate-rg}"
    local location="${AZURE_LOCATION:-westeurope}"
    
    info "Checking Terraform backend storage account..."
    
    # Check if storage account exists
    local storage_account=$(az storage account list --resource-group "$tfstate_rg" --query "[?contains(name, 'tfstate')].name" -o tsv 2>/dev/null | head -n 1 || echo "")
    
    if [ -z "$storage_account" ]; then
        warn "Terraform backend storage account not found."
        read -p "Do you want to create a new storage account for Terraform backend? (y/n): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            # Generate random suffix for storage account name
            local random_suffix=$(openssl rand -hex 4 2>/dev/null || echo $(date +%s | sha256sum | head -c 8))
            storage_account="tfstate${random_suffix}"
            
            log "Creating resource group: $tfstate_rg"
            az group create --name "$tfstate_rg" --location "$location" --output none 2>/dev/null || true
            
            log "Creating storage account: $storage_account"
            az storage account create \
                --resource-group "$tfstate_rg" \
                --name "$storage_account" \
                --sku Standard_LRS \
                --kind StorageV2 \
                --location "$location" \
                --output none || error "Failed to create storage account"
            
            log "Creating storage container: tfstate"
            az storage container create \
                --name "tfstate" \
                --account-name "$storage_account" \
                --output none || error "Failed to create storage container"
            
            log "Storage account created: $storage_account"
        else
            warn "Skipping storage account creation. You'll need to set ARM_STORAGE_ACCOUNT_NAME manually."
            return 1
        fi
    else
        log "Found existing storage account: $storage_account"
    fi
    
    # Get access key
    local access_key=$(az storage account keys list \
        --resource-group "$tfstate_rg" \
        --account-name "$storage_account" \
        --query "[0].value" -o tsv 2>/dev/null || echo "")
    
    if [ -z "$access_key" ]; then
        warn "Could not get storage account access key"
        return 1
    fi
    
    # Return values (we'll set them in the env file)
    echo "STORAGE_ACCOUNT=$storage_account"
    echo "STORAGE_RG=$tfstate_rg"
    echo "ACCESS_KEY=$access_key"
}

# Prompt for Cloudflare values
get_cloudflare_values() {
    info "Cloudflare configuration required"
    info "You can find these values in your Cloudflare dashboard:"
    info "  - Zone ID: Cloudflare Dashboard > Your Domain > Overview > Zone ID"
    info "  - API Token: Cloudflare Dashboard > My Profile > API Tokens > Create Token"
    
    echo
    
    # Zone ID
    if [ -z "${CLOUDFLARE_ZONE_ID:-}" ]; then
        prompt "Enter Cloudflare Zone ID:"
        read -r zone_id
        if [ -z "$zone_id" ]; then
            warn "Zone ID not provided. Skipping Cloudflare configuration."
            return 1
        fi
    else
        zone_id="${CLOUDFLARE_ZONE_ID}"
        log "Using existing CLOUDFLARE_ZONE_ID"
    fi
    
    # API Token
    if [ -z "${CLOUDFLARE_API_TOKEN:-}" ]; then
        prompt "Enter Cloudflare API Token:"
        read -rs api_token
        echo
        if [ -z "$api_token" ]; then
            warn "API Token not provided. Skipping Cloudflare configuration."
            return 1
        fi
    else
        api_token="${CLOUDFLARE_API_TOKEN}"
        log "Using existing CLOUDFLARE_API_TOKEN"
    fi
    
    echo "CLOUDFLARE_ZONE_ID=$zone_id"
    echo "CLOUDFLARE_API_TOKEN=$api_token"
}

# Update .env file
update_env_file() {
    local updates="$1"
    
    info "Updating .env file..."
    
    # Create .env file if it doesn't exist
    if [ ! -f "$ENV_FILE" ]; then
        log "Creating .env file..."
        touch "$ENV_FILE"
    fi
    
    # Process each update
    while IFS= read -r line; do
        if [ -z "$line" ]; then
            continue
        fi
        
        local key=$(echo "$line" | cut -d'=' -f1)
        local value=$(echo "$line" | cut -d'=' -f2-)
        
        # Remove quotes if present
        value=$(echo "$value" | sed 's/^"//;s/"$//')
        
        # Check if key exists in .env file
        if grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then
            # Update existing value
            if [[ "$OSTYPE" == "darwin"* ]]; then
                # macOS
                sed -i '' "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
            else
                # Linux
                sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
            fi
            log "Updated: $key"
        else
            # Append new value
            echo "${key}=${value}" >> "$ENV_FILE"
            log "Added: $key"
        fi
    done <<< "$updates"
    
    log ".env file updated successfully"
}

# Main function
main() {
    log "Populating .env file with Azure and Cloudflare values"
    log "======================================================"
    echo
    
    # Check prerequisites
    check_azure_cli
    check_azure_login
    
    # Collect all updates
    local updates=""
    
    # Get Azure values
    info "Retrieving Azure configuration..."
    
    local sub_id=$(get_azure_subscription_id)
    if [ -n "$sub_id" ]; then
        updates+="AZURE_SUBSCRIPTION_ID=$sub_id"$'\n'
        log "Azure Subscription ID: $sub_id"
    else
        warn "Could not retrieve Azure Subscription ID"
    fi
    
    local tenant_id=$(get_azure_tenant_id)
    if [ -n "$tenant_id" ]; then
        updates+="AZURE_TENANT_ID=$tenant_id"$'\n'
        log "Azure Tenant ID: $tenant_id"
    else
        warn "Could not retrieve Azure Tenant ID"
    fi
    
    local rg=$(get_azure_resource_group)
    updates+="AZURE_RESOURCE_GROUP=$rg"$'\n'
    log "Azure Resource Group: $rg"
    
    # Get Terraform backend info
    echo
    info "Checking Terraform backend storage..."
    local backend_info=$(get_terraform_backend_info)
    if [ -n "$backend_info" ]; then
        while IFS= read -r line; do
            if [[ "$line" == STORAGE_ACCOUNT=* ]]; then
                updates+="ARM_STORAGE_ACCOUNT_NAME=$(echo "$line" | cut -d'=' -f2-)"$'\n'
            elif [[ "$line" == STORAGE_RG=* ]]; then
                updates+="ARM_RESOURCE_GROUP_NAME=$(echo "$line" | cut -d'=' -f2-)"$'\n'
            elif [[ "$line" == ACCESS_KEY=* ]]; then
                updates+="ARM_ACCESS_KEY=$(echo "$line" | cut -d'=' -f2-)"$'\n'
            fi
        done <<< "$backend_info"
        updates+="ARM_CONTAINER_NAME=tfstate"$'\n'
    else
        warn "Terraform backend configuration skipped"
    fi
    
    # Get Cloudflare values
    echo
    local cloudflare_info=$(get_cloudflare_values)
    if [ -n "$cloudflare_info" ]; then
        updates+="$cloudflare_info"$'\n'
    else
        warn "Cloudflare configuration skipped"
    fi
    
    # Update .env file
    echo
    if [ -n "$updates" ]; then
        update_env_file "$updates"
        echo
        log "Summary of updates:"
        echo "$updates" | grep -v "^$" | while IFS= read -r line; do
            local key=$(echo "$line" | cut -d'=' -f1)
            if [[ "$key" == *"TOKEN"* ]] || [[ "$key" == *"SECRET"* ]] || [[ "$key" == *"KEY"* ]]; then
                echo "  $key=*** (hidden)"
            else
                echo "  $line"
            fi
        done
    else
        warn "No updates to apply"
    fi
    
    echo
    log "Done! Review your .env file at: $ENV_FILE"
    log "Note: Sensitive values (tokens, keys, secrets) are hidden in the summary above"
}

# Run main function
main "$@"

