# ============================================================================
# ShopDB Form Testing Script
# ============================================================================
# Tests form submissions across key pages to verify no errors occur
# Run from PowerShell on a machine that can reach the dev server
# ============================================================================

param(
    [string]$BaseUrl = "http://192.168.122.151:8080",
    [switch]$Verbose
)

$ErrorActionPreference = "Continue"
$TestResults = @()

function Write-TestResult {
    param(
        [string]$TestName,
        [bool]$Passed,
        [string]$Message = ""
    )

    $status = if ($Passed) { "PASS" } else { "FAIL" }
    $color = if ($Passed) { "Green" } else { "Red" }

    Write-Host "[$status] $TestName" -ForegroundColor $color
    if ($Message -and $Verbose) {
        Write-Host "        $Message" -ForegroundColor Gray
    }

    $script:TestResults += [PSCustomObject]@{
        Test = $TestName
        Status = $status
        Message = $Message
    }
}

function Test-PageLoads {
    param([string]$Url, [string]$TestName, [string]$ExpectedContent = "")

    try {
        $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 30
        $passed = $response.StatusCode -eq 200

        if ($passed -and $ExpectedContent) {
            $passed = $response.Content -match $ExpectedContent
        }

        # Check for ASP errors
        if ($response.Content -match "error|Error 500|Microsoft VBScript") {
            $passed = $false
            Write-TestResult -TestName $TestName -Passed $false -Message "Page contains error text"
            return $false
        }

        Write-TestResult -TestName $TestName -Passed $passed -Message "Status: $($response.StatusCode)"
        return $passed
    }
    catch {
        Write-TestResult -TestName $TestName -Passed $false -Message $_.Exception.Message
        return $false
    }
}

function Test-FormSubmission {
    param(
        [string]$Url,
        [string]$TestName,
        [hashtable]$FormData,
        [string]$ExpectedRedirect = "",
        [string]$ExpectedContent = ""
    )

    try {
        # Submit form
        $response = Invoke-WebRequest -Uri $Url -Method POST -Body $FormData -UseBasicParsing -TimeoutSec 30 -MaximumRedirection 0 -ErrorAction SilentlyContinue

        $passed = $true
        $message = "Status: $($response.StatusCode)"

        # Check for redirect (302) which usually means success
        if ($response.StatusCode -eq 302) {
            $message = "Redirected to: $($response.Headers.Location)"
            if ($ExpectedRedirect -and $response.Headers.Location -notmatch $ExpectedRedirect) {
                $passed = $false
            }
        }
        # Check for 200 with expected content
        elseif ($response.StatusCode -eq 200) {
            if ($ExpectedContent -and $response.Content -notmatch $ExpectedContent) {
                $passed = $false
            }
            # Check for error messages in response
            if ($response.Content -match "Error:|error|Microsoft VBScript|500") {
                $passed = $false
                $message = "Response contains error text"
            }
        }
        else {
            $passed = $false
        }

        Write-TestResult -TestName $TestName -Passed $passed -Message $message
        return $passed
    }
    catch {
        # 302 redirects throw exceptions with -MaximumRedirection 0
        if ($_.Exception.Response.StatusCode -eq 302 -or $_.Exception.Message -match "302") {
            Write-TestResult -TestName $TestName -Passed $true -Message "Redirected (success)"
            return $true
        }
        Write-TestResult -TestName $TestName -Passed $false -Message $_.Exception.Message
        return $false
    }
}

# ============================================================================
# START TESTS
# ============================================================================

Write-Host ""
Write-Host "============================================" -ForegroundColor Cyan
Write-Host "ShopDB Form Testing - $(Get-Date)" -ForegroundColor Cyan
Write-Host "Base URL: $BaseUrl" -ForegroundColor Cyan
Write-Host "============================================" -ForegroundColor Cyan
Write-Host ""

# ----------------------------------------------------------------------------
# 1. PAGE LOAD TESTS
# ----------------------------------------------------------------------------
Write-Host "--- PAGE LOAD TESTS ---" -ForegroundColor Yellow

Test-PageLoads -Url "$BaseUrl/default.asp" -TestName "Dashboard loads" -ExpectedContent "Dashboard"
Test-PageLoads -Url "$BaseUrl/displaynotifications.asp" -TestName "Notifications list loads" -ExpectedContent "Notification"
Test-PageLoads -Url "$BaseUrl/addnotification.asp" -TestName "Add notification form loads" -ExpectedContent "Add Notification"
Test-PageLoads -Url "$BaseUrl/displayapplications.asp" -TestName "Applications list loads" -ExpectedContent "Application"
Test-PageLoads -Url "$BaseUrl/displayprinters.asp" -TestName "Printers list loads" -ExpectedContent "Printer"
Test-PageLoads -Url "$BaseUrl/displaypcs.asp" -TestName "PCs list loads" -ExpectedContent "PC"
Test-PageLoads -Url "$BaseUrl/displaymachines.asp" -TestName "Machines list loads" -ExpectedContent "Machine"
Test-PageLoads -Url "$BaseUrl/network_devices.asp" -TestName "Network devices loads" -ExpectedContent "Network"

Write-Host ""

# ----------------------------------------------------------------------------
# 2. NOTIFICATION FORM TESTS
# ----------------------------------------------------------------------------
Write-Host "--- NOTIFICATION FORM TESTS ---" -ForegroundColor Yellow

# Test: Create notification with all fields
$notificationData = @{
    notification = "Test notification from automated testing - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
    notificationtypeid = "2"  # Awareness
    businessunitid = ""       # All business units
    appid = ""                # No application
    ticketnumber = "GETEST123456"
    starttime = (Get-Date).ToString("yyyy-MM-ddTHH:mm")
    endtime = (Get-Date).AddDays(1).ToString("yyyy-MM-ddTHH:mm")
    isactive = "1"
    isshopfloor = "0"
}
Test-FormSubmission -Url "$BaseUrl/savenotification_direct.asp" -TestName "Create notification (basic)" -FormData $notificationData -ExpectedRedirect "displaynotifications"

# Test: Create notification with application linked
$notificationWithApp = @{
    notification = "Test with app link - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
    notificationtypeid = "3"  # Change
    businessunitid = "2"      # Specific BU
    appid = "6"               # PC-DMIS
    ticketnumber = "GECHG123456"
    starttime = (Get-Date).ToString("yyyy-MM-ddTHH:mm")
    endtime = (Get-Date).AddHours(4).ToString("yyyy-MM-ddTHH:mm")
    isactive = "1"
    isshopfloor = "1"
}
Test-FormSubmission -Url "$BaseUrl/savenotification_direct.asp" -TestName "Create notification (with app)" -FormData $notificationWithApp -ExpectedRedirect "displaynotifications"

# Test: Create notification without end time (indefinite)
$notificationIndefinite = @{
    notification = "Indefinite test notification - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
    notificationtypeid = "4"  # Incident
    businessunitid = ""
    appid = ""
    ticketnumber = ""
    starttime = (Get-Date).ToString("yyyy-MM-ddTHH:mm")
    endtime = ""              # Indefinite
    isactive = "1"
    isshopfloor = "0"
}
Test-FormSubmission -Url "$BaseUrl/savenotification_direct.asp" -TestName "Create notification (indefinite)" -FormData $notificationIndefinite -ExpectedRedirect "displaynotifications"

Write-Host ""

# ----------------------------------------------------------------------------
# 3. API ENDPOINT TESTS
# ----------------------------------------------------------------------------
Write-Host "--- API ENDPOINT TESTS ---" -ForegroundColor Yellow

# Test: API health check
Test-PageLoads -Url "$BaseUrl/api.asp?action=getDashboardData" -TestName "API getDashboardData" -ExpectedContent "success"

# Test: API with POST data (updateCompleteAsset simulation)
$apiTestData = @{
    action = "updateCompleteAsset"
    hostname = "TEST-PC-001"
    serialNumber = "TESTSERIAL123"
    model = "Test Model"
    manufacturer = "Test Manufacturer"
    macAddress = "00:11:22:33:44:55"
    ipAddress = "192.168.1.100"
    osVersion = "Windows 11 Pro"
    lastUser = "testuser"
    pcType = "Shopfloor"
}
# Note: This may fail if PC doesn't exist - that's expected
Test-FormSubmission -Url "$BaseUrl/api.asp" -TestName "API updateCompleteAsset" -FormData $apiTestData -ExpectedContent "success|error"

Write-Host ""

# ----------------------------------------------------------------------------
# 4. EDIT FORM TESTS (requires existing records)
# ----------------------------------------------------------------------------
Write-Host "--- EDIT FORM TESTS ---" -ForegroundColor Yellow

# Get a notification ID to test editing
try {
    $notifPage = Invoke-WebRequest -Uri "$BaseUrl/displaynotifications.asp" -UseBasicParsing
    if ($notifPage.Content -match 'editnotification\.asp\?notificationid=(\d+)') {
        $testNotifId = $Matches[1]

        Test-PageLoads -Url "$BaseUrl/editnotification.asp?notificationid=$testNotifId" -TestName "Edit notification form loads" -ExpectedContent "Edit Notification"

        # Test updating a notification
        $updateData = @{
            notificationid = $testNotifId
            notification = "Updated by test script - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
            notificationtypeid = "2"
            businessunitid = ""
            appid = ""
            ticketnumber = "GETEST-UPDATE"
            starttime = (Get-Date).ToString("yyyy-MM-ddTHH:mm")
            endtime = (Get-Date).AddDays(1).ToString("yyyy-MM-ddTHH:mm")
            isactive = "1"
            isactive_submitted = "1"
            isshopfloor = "0"
            isshopfloor_submitted = "1"
        }
        Test-FormSubmission -Url "$BaseUrl/updatenotification_direct.asp" -TestName "Update notification" -FormData $updateData -ExpectedRedirect "displaynotifications"
    }
    else {
        Write-TestResult -TestName "Edit notification form loads" -Passed $false -Message "No notifications found to test"
    }
}
catch {
    Write-TestResult -TestName "Edit notification tests" -Passed $false -Message $_.Exception.Message
}

Write-Host ""

# ----------------------------------------------------------------------------
# 5. VALIDATION TESTS (should fail gracefully)
# ----------------------------------------------------------------------------
Write-Host "--- VALIDATION TESTS ---" -ForegroundColor Yellow

# Test: Missing required fields
$invalidNotification = @{
    notification = ""  # Required field empty
    notificationtypeid = "1"
    starttime = ""     # Required field empty
}
# This should NOT redirect to displaynotifications, it should show an error or stay on form
try {
    $response = Invoke-WebRequest -Uri "$BaseUrl/savenotification_direct.asp" -Method POST -Body $invalidNotification -UseBasicParsing -MaximumRedirection 0 -ErrorAction SilentlyContinue
    $passed = $response.Content -match "Required|missing|error" -or $response.StatusCode -eq 200
    Write-TestResult -TestName "Reject empty required fields" -Passed $passed -Message "Response handled gracefully"
}
catch {
    # If it redirects anyway, that's a problem
    if ($_.Exception.Message -match "302") {
        Write-TestResult -TestName "Reject empty required fields" -Passed $false -Message "Should not redirect with missing required fields"
    }
    else {
        Write-TestResult -TestName "Reject empty required fields" -Passed $true -Message "Validation working"
    }
}

Write-Host ""

# ============================================================================
# SUMMARY
# ============================================================================
Write-Host "============================================" -ForegroundColor Cyan
Write-Host "TEST SUMMARY" -ForegroundColor Cyan
Write-Host "============================================" -ForegroundColor Cyan

$passed = ($TestResults | Where-Object { $_.Status -eq "PASS" }).Count
$failed = ($TestResults | Where-Object { $_.Status -eq "FAIL" }).Count
$total = $TestResults.Count

Write-Host ""
Write-Host "Total Tests: $total" -ForegroundColor White
Write-Host "Passed: $passed" -ForegroundColor Green
Write-Host "Failed: $failed" -ForegroundColor $(if ($failed -gt 0) { "Red" } else { "Green" })
Write-Host ""

if ($failed -gt 0) {
    Write-Host "FAILED TESTS:" -ForegroundColor Red
    $TestResults | Where-Object { $_.Status -eq "FAIL" } | ForEach-Object {
        Write-Host "  - $($_.Test): $($_.Message)" -ForegroundColor Red
    }
}

Write-Host ""
Write-Host "Testing completed at $(Get-Date)" -ForegroundColor Cyan
