#!/bin/bash
# scripts/smoke-tests.sh - Smoke tests for deployed infrastructure

set -e

# Arguments
ENVIRONMENT=${1:-dev}
APP_URL=${2:-}

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

# Test results
TESTS_PASSED=0
TESTS_FAILED=0

# Functions
log_test() {
    echo -e "\n🧪 Testing: $1"
}

log_pass() {
    echo -e "${GREEN}✅ PASS${NC}: $1"
    ((TESTS_PASSED++))
}

log_fail() {
    echo -e "${RED}❌ FAIL${NC}: $1"
    ((TESTS_FAILED++))
}

log_warn() {
    echo -e "${YELLOW}⚠️  WARN${NC}: $1"
}

# Test Azure connectivity
test_azure_connectivity() {
    log_test "Azure Connectivity"
    
    if az account show &> /dev/null; then
        ACCOUNT=$(az account show --query name -o tsv)
        log_pass "Connected to Azure account: $ACCOUNT"
    else
        log_fail "Not connected to Azure"
        return 1
    fi
}

# Test resource group exists
test_resource_group() {
    log_test "Resource Group"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    
    if az group exists --name "$RG_NAME" | grep -q true; then
        log_pass "Resource group exists: $RG_NAME"
        
        # Get resource count
        RESOURCE_COUNT=$(az resource list --resource-group "$RG_NAME" --query "length(@)" -o tsv)
        log_pass "Resource count: $RESOURCE_COUNT"
    else
        log_fail "Resource group not found: $RG_NAME"
        return 1
    fi
}

# Test web app
test_web_app() {
    log_test "Web Application"
    
    if [ -z "$APP_URL" ]; then
        # Try to find web app URL
        RG_NAME="rg-workshop13-${ENVIRONMENT}"
        WEB_APP=$(az webapp list --resource-group "$RG_NAME" --query "[0].name" -o tsv 2>/dev/null || echo "")
        
        if [ -n "$WEB_APP" ]; then
            APP_URL="https://$(az webapp show --name "$WEB_APP" --resource-group "$RG_NAME" --query defaultHostName -o tsv)"
        else
            log_fail "No web app found and no URL provided"
            return 1
        fi
    fi
    
    # Test HTTP response
    HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$APP_URL" || echo "000")
    
    if [[ "$HTTP_CODE" =~ ^(200|404)$ ]]; then
        log_pass "Web app responding: $APP_URL (HTTP $HTTP_CODE)"
    else
        log_fail "Web app not responding: $APP_URL (HTTP $HTTP_CODE)"
    fi
    
    # Test HTTPS enforcement
    HTTP_URL="${APP_URL/https:/http:}"
    REDIRECT_CODE=$(curl -s -o /dev/null -w "%{http_code}" -L "$HTTP_URL" || echo "000")
    
    if [[ "$REDIRECT_CODE" == "200" ]]; then
        log_pass "HTTPS redirect working"
    else
        log_warn "HTTPS redirect may not be configured"
    fi
}

# Test storage account
test_storage_account() {
    log_test "Storage Account"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    STORAGE_ACCOUNT=$(az storage account list --resource-group "$RG_NAME" --query "[0].name" -o tsv 2>/dev/null || echo "")
    
    if [ -n "$STORAGE_ACCOUNT" ]; then
        log_pass "Storage account found: $STORAGE_ACCOUNT"
        
        # Check encryption
        ENCRYPTION=$(az storage account show --name "$STORAGE_ACCOUNT" --resource-group "$RG_NAME" \
            --query "encryption.services.blob.enabled" -o tsv)
        
        if [ "$ENCRYPTION" == "true" ]; then
            log_pass "Storage encryption enabled"
        else
            log_fail "Storage encryption not enabled"
        fi
        
        # Check HTTPS only
        HTTPS_ONLY=$(az storage account show --name "$STORAGE_ACCOUNT" --resource-group "$RG_NAME" \
            --query "supportsHttpsTrafficOnly" -o tsv)
        
        if [ "$HTTPS_ONLY" == "true" ]; then
            log_pass "HTTPS-only traffic enforced"
        else
            log_fail "HTTPS-only traffic not enforced"
        fi
    else
        log_fail "No storage account found"
    fi
}

# Test Key Vault
test_key_vault() {
    log_test "Key Vault"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    KEY_VAULT=$(az keyvault list --resource-group "$RG_NAME" --query "[0].name" -o tsv 2>/dev/null || echo "")
    
    if [ -n "$KEY_VAULT" ]; then
        log_pass "Key Vault found: $KEY_VAULT"
        
        # Check soft delete
        SOFT_DELETE=$(az keyvault show --name "$KEY_VAULT" \
            --query "properties.enableSoftDelete" -o tsv)
        
        if [ "$SOFT_DELETE" == "true" ]; then
            log_pass "Soft delete enabled"
        else
            log_fail "Soft delete not enabled"
        fi
        
        # Check RBAC
        RBAC=$(az keyvault show --name "$KEY_VAULT" \
            --query "properties.enableRbacAuthorization" -o tsv)
        
        if [ "$RBAC" == "true" ]; then
            log_pass "RBAC authorization enabled"
        else
            log_warn "RBAC authorization not enabled (using access policies)"
        fi
    else
        log_warn "No Key Vault found (may not be required for all exercises)"
    fi
}

# Test Application Insights
test_app_insights() {
    log_test "Application Insights"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    APP_INSIGHTS=$(az monitor app-insights component list --resource-group "$RG_NAME" \
        --query "[0].name" -o tsv 2>/dev/null || echo "")
    
    if [ -n "$APP_INSIGHTS" ]; then
        log_pass "Application Insights found: $APP_INSIGHTS"
        
        # Check if connected to Log Analytics
        WORKSPACE_ID=$(az monitor app-insights component show \
            --app "$APP_INSIGHTS" --resource-group "$RG_NAME" \
            --query "workspaceResourceId" -o tsv 2>/dev/null || echo "")
        
        if [ -n "$WORKSPACE_ID" ] && [ "$WORKSPACE_ID" != "null" ]; then
            log_pass "Connected to Log Analytics workspace"
        else
            log_warn "Not using workspace-based Application Insights"
        fi
    else
        log_fail "No Application Insights found"
    fi
}

# Test tags
test_resource_tags() {
    log_test "Resource Tags"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    
    # Check resource group tags
    RG_TAGS=$(az group show --name "$RG_NAME" --query "tags" -o json 2>/dev/null || echo "{}")
    
    REQUIRED_TAGS=("Environment" "Module" "ManagedBy")
    MISSING_TAGS=()
    
    for tag in "${REQUIRED_TAGS[@]}"; do
        if ! echo "$RG_TAGS" | jq -e "has(\"$tag\")" &> /dev/null; then
            MISSING_TAGS+=("$tag")
        fi
    done
    
    if [ ${#MISSING_TAGS[@]} -eq 0 ]; then
        log_pass "All required tags present on resource group"
    else
        log_fail "Missing tags on resource group: ${MISSING_TAGS[*]}"
    fi
    
    # Sample check on resources
    RESOURCE_COUNT=$(az resource list --resource-group "$RG_NAME" \
        --query "length([?tags.Module=='Module-13' || tags.Module=='13'])" -o tsv)
    
    if [ "$RESOURCE_COUNT" -gt 0 ]; then
        log_pass "Found $RESOURCE_COUNT resources with Module tag"
    else
        log_warn "No resources found with Module tag"
    fi
}

# Test network security
test_network_security() {
    log_test "Network Security"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    
    # Check for NSGs
    NSG_COUNT=$(az network nsg list --resource-group "$RG_NAME" --query "length(@)" -o tsv 2>/dev/null || echo "0")
    
    if [ "$NSG_COUNT" -gt 0 ]; then
        log_pass "Found $NSG_COUNT Network Security Group(s)"
        
        # Check for open ports
        OPEN_SSH=$(az network nsg rule list --resource-group "$RG_NAME" \
            --nsg-name $(az network nsg list --resource-group "$RG_NAME" --query "[0].name" -o tsv) \
            --query "[?destinationPortRange=='22' && access=='Allow' && sourceAddressPrefix=='*'].name" \
            -o tsv 2>/dev/null || echo "")
        
        if [ -z "$OPEN_SSH" ]; then
            log_pass "SSH port not open to internet"
        else
            log_fail "SSH port open to internet - security risk!"
        fi
    else
        log_warn "No Network Security Groups found"
    fi
}

# Test for production-specific features
test_production_features() {
    if [ "$ENVIRONMENT" != "prod" ]; then
        return 0
    fi
    
    log_test "Production-Specific Features"
    
    RG_NAME="rg-workshop13-${ENVIRONMENT}"
    
    # Check for staging slots
    WEB_APP=$(az webapp list --resource-group "$RG_NAME" --query "[0].name" -o tsv 2>/dev/null || echo "")
    if [ -n "$WEB_APP" ]; then
        SLOT_COUNT=$(az webapp deployment slot list --name "$WEB_APP" --resource-group "$RG_NAME" \
            --query "length(@)" -o tsv 2>/dev/null || echo "0")
        
        if [ "$SLOT_COUNT" -gt 0 ]; then
            log_pass "Staging slots configured: $SLOT_COUNT"
        else
            log_warn "No staging slots found for production"
        fi
    fi
    
    # Check for autoscaling
    AUTOSCALE=$(az monitor autoscale list --resource-group "$RG_NAME" \
        --query "length(@)" -o tsv 2>/dev/null || echo "0")
    
    if [ "$AUTOSCALE" -gt 0 ]; then
        log_pass "Autoscaling configured"
    else
        log_warn "No autoscaling found for production"
    fi
}

# Performance test
test_performance() {
    log_test "Basic Performance"
    
    if [ -n "$APP_URL" ]; then
        # Measure response time
        RESPONSE_TIME=$(curl -o /dev/null -s -w '%{time_total}' "$APP_URL" || echo "999")
        
        if (( $(echo "$RESPONSE_TIME < 2.0" | bc -l) )); then
            log_pass "Response time acceptable: ${RESPONSE_TIME}s"
        else
            log_warn "Slow response time: ${RESPONSE_TIME}s"
        fi
    fi
}

# Main test execution
main() {
    echo "🚀 Infrastructure Smoke Tests - Module 13"
    echo "========================================"
    echo "Environment: $ENVIRONMENT"
    echo "App URL: ${APP_URL:-<will be discovered>}"
    echo ""
    
    # Run all tests
    test_azure_connectivity
    test_resource_group
    test_web_app
    test_storage_account
    test_key_vault
    test_app_insights
    test_resource_tags
    test_network_security
    test_production_features
    test_performance
    
    # Summary
    echo ""
    echo "========================================"
    echo "Test Summary"
    echo "========================================"
    echo -e "${GREEN}Passed:${NC} $TESTS_PASSED"
    echo -e "${RED}Failed:${NC} $TESTS_FAILED"
    echo ""
    
    if [ $TESTS_FAILED -eq 0 ]; then
        echo -e "${GREEN}🎉 All tests passed!${NC}"
        exit 0
    else
        echo -e "${RED}⚠️  Some tests failed${NC}"
        exit 1
    fi
}

# Run main
main