# ColaFlow Day 5 Integration Tests
# Simple ASCII-only version

$baseUrl = "http://localhost:5167"
$ErrorActionPreference = "Continue"

$testsPassed = 0
$testsFailed = 0
$testsTotal = 0

function Test-Success {
    param($Name)
    $script:testsPassed++
    $script:testsTotal++
    Write-Host "[PASS] $Name" -ForegroundColor Green
}

function Test-Failure {
    param($Name, $Error)
    $script:testsFailed++
    $script:testsTotal++
    Write-Host "[FAIL] $Name" -ForegroundColor Red
    Write-Host "       Error: $Error" -ForegroundColor DarkRed
}

Write-Host "================================================" -ForegroundColor Cyan
Write-Host "ColaFlow Day 5 Integration Test Suite" -ForegroundColor Cyan
Write-Host "Testing: Refresh Token + RBAC" -ForegroundColor Cyan
Write-Host "================================================" -ForegroundColor Cyan
Write-Host ""

# Wait for API
Write-Host "Waiting for API server..." -ForegroundColor Yellow
Start-Sleep -Seconds 8

# =============================
# PHASE 1: REFRESH TOKEN TESTS
# =============================

Write-Host "`n--- PHASE 1: REFRESH TOKEN TESTS ---`n" -ForegroundColor Yellow

# Test 1: Register and get tokens
Write-Host "[Test 1] Register tenant and get tokens" -ForegroundColor White
$slug1 = "test-$(Get-Random -Minimum 1000 -Maximum 9999)"
$body1 = @{
    tenantName = "Test Corp"
    tenantSlug = $slug1
    subscriptionPlan = "Professional"
    adminEmail = "admin@test.com"
    adminPassword = "Admin@1234"
    adminFullName = "Admin"
} | ConvertTo-Json

try {
    $reg1 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body1
    $token1 = $reg1.accessToken
    $refresh1 = $reg1.refreshToken

    if ($token1 -and $refresh1) {
        Test-Success "Register returns access token and refresh token"
    } else {
        Test-Failure "Register returns tokens" "Missing tokens"
    }
} catch {
    Test-Failure "Register tenant" $_.Exception.Message
    exit 1
}

# Test 2: Use access token
Write-Host "`n[Test 2] Use access token" -ForegroundColor White
try {
    $headers1 = @{ "Authorization" = "Bearer $token1" }
    $me1 = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $headers1

    if ($me1.userId) {
        Test-Success "Access token works for /api/auth/me"
    } else {
        Test-Failure "Access token" "No user data returned"
    }
} catch {
    Test-Failure "Use access token" $_.Exception.Message
}

# Test 3: Refresh token
Write-Host "`n[Test 3] Refresh access token" -ForegroundColor White
try {
    $refreshBody1 = @{ refreshToken = $refresh1 } | ConvertTo-Json
    $refRes1 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $refreshBody1

    $token2 = $refRes1.accessToken
    $refresh2 = $refRes1.refreshToken

    if ($token2 -and $refresh2 -and $token2 -ne $token1 -and $refresh2 -ne $refresh1) {
        Test-Success "Token refresh generates new tokens"
    } else {
        Test-Failure "Token refresh" "Tokens not rotated"
    }
} catch {
    Test-Failure "Refresh token" $_.Exception.Message
}

# Test 4: Old token rejected
Write-Host "`n[Test 4] Old refresh token rejected" -ForegroundColor White
try {
    $oldBody = @{ refreshToken = $refresh1 } | ConvertTo-Json
    try {
        $bad = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $oldBody
        Test-Failure "Old token rejection" "Old token was accepted!"
    } catch {
        $code = $_.Exception.Response.StatusCode.value__
        if ($code -eq 401) {
            Test-Success "Old refresh token rejected (401)"
        } else {
            Test-Failure "Old token rejection" "Got status $code instead of 401"
        }
    }
} catch {
    Test-Failure "Old token test" $_.Exception.Message
}

# Test 5: New token works
Write-Host "`n[Test 5] New access token works" -ForegroundColor White
try {
    $headers2 = @{ "Authorization" = "Bearer $token2" }
    $me2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $headers2

    if ($me2.userId -eq $me1.userId) {
        Test-Success "New access token works"
    } else {
        Test-Failure "New access token" "User mismatch"
    }
} catch {
    Test-Failure "New access token" $_.Exception.Message
}

# Test 6: Logout
Write-Host "`n[Test 6] Logout revokes token" -ForegroundColor White
try {
    $logoutBody = @{ refreshToken = $refresh2 } | ConvertTo-Json
    $logout = Invoke-RestMethod -Uri "$baseUrl/api/auth/logout" -Method Post -ContentType "application/json" -Body $logoutBody

    if ($logout.message -like "*success*") {
        Test-Success "Logout successful"
    } else {
        Test-Failure "Logout" "No success message"
    }
} catch {
    Test-Failure "Logout" $_.Exception.Message
}

# Test 7: Revoked token rejected
Write-Host "`n[Test 7] Revoked token rejected" -ForegroundColor White
try {
    $revokeBody = @{ refreshToken = $refresh2 } | ConvertTo-Json
    try {
        $bad2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $revokeBody
        Test-Failure "Revoked token rejection" "Revoked token accepted!"
    } catch {
        $code = $_.Exception.Response.StatusCode.value__
        if ($code -eq 401) {
            Test-Success "Revoked token rejected (401)"
        } else {
            Test-Failure "Revoked token rejection" "Got status $code"
        }
    }
} catch {
    Test-Failure "Revoked token test" $_.Exception.Message
}

# ======================
# PHASE 2: RBAC TESTS
# ======================

Write-Host "`n--- PHASE 2: RBAC TESTS ---`n" -ForegroundColor Yellow

# Test 8: Register for RBAC
Write-Host "[Test 8] Register tenant for RBAC test" -ForegroundColor White
$slug2 = "rbac-$(Get-Random -Minimum 1000 -Maximum 9999)"
$body2 = @{
    tenantName = "RBAC Corp"
    tenantSlug = $slug2
    subscriptionPlan = "Professional"
    adminEmail = "rbac@test.com"
    adminPassword = "Admin@1234"
    adminFullName = "RBAC Admin"
} | ConvertTo-Json

try {
    $reg2 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body2
    $rbacToken = $reg2.accessToken
    $rbacRefresh = $reg2.refreshToken
    Test-Success "RBAC test tenant registered"
} catch {
    Test-Failure "RBAC tenant registration" $_.Exception.Message
}

# Test 9: Verify TenantOwner role
Write-Host "`n[Test 9] Verify TenantOwner role assigned" -ForegroundColor White
try {
    $rbacHeaders = @{ "Authorization" = "Bearer $rbacToken" }
    $rbacMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $rbacHeaders

    if ($rbacMe.tenantRole -eq "TenantOwner" -and $rbacMe.role -eq "TenantOwner") {
        Test-Success "TenantOwner role correctly assigned"
    } else {
        Test-Failure "TenantOwner role" "Got: tenantRole=$($rbacMe.tenantRole), role=$($rbacMe.role)"
    }
} catch {
    Test-Failure "Role verification" $_.Exception.Message
}

# Test 10: Role persistence after login
Write-Host "`n[Test 10] Role persists after login" -ForegroundColor White
try {
    $loginBody = @{
        tenantSlug = $slug2
        email = "rbac@test.com"
        password = "Admin@1234"
    } | ConvertTo-Json

    $login = Invoke-RestMethod -Uri "$baseUrl/api/auth/login" -Method Post -ContentType "application/json" -Body $loginBody
    $loginToken = $login.accessToken

    $loginHeaders = @{ "Authorization" = "Bearer $loginToken" }
    $loginMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $loginHeaders

    if ($loginMe.tenantRole -eq "TenantOwner") {
        Test-Success "Role persists after login"
    } else {
        Test-Failure "Role persistence" "Got: $($loginMe.tenantRole)"
    }
} catch {
    Test-Failure "Login role persistence" $_.Exception.Message
}

# Test 11: Role in refreshed token
Write-Host "`n[Test 11] Role preserved in refreshed token" -ForegroundColor White
try {
    $refreshBody2 = @{ refreshToken = $rbacRefresh } | ConvertTo-Json
    $refRes2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $refreshBody2

    $refreshedToken = $refRes2.accessToken
    $refreshedHeaders = @{ "Authorization" = "Bearer $refreshedToken" }
    $refreshedMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $refreshedHeaders

    if ($refreshedMe.tenantRole -eq "TenantOwner") {
        Test-Success "Role preserved in refreshed token"
    } else {
        Test-Failure "Role in refreshed token" "Got: $($refreshedMe.tenantRole)"
    }
} catch {
    Test-Failure "Refreshed token role" $_.Exception.Message
}

# Test 12: JWT claims present
Write-Host "`n[Test 12] All required JWT claims present" -ForegroundColor White
try {
    $claimsHeaders = @{ "Authorization" = "Bearer $rbacToken" }
    $claims = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $claimsHeaders

    $hasAll = $claims.userId -and $claims.email -and $claims.tenantRole -and $claims.role -and $claims.tenantId

    if ($hasAll) {
        Test-Success "All required claims present"
    } else {
        Test-Failure "JWT claims" "Missing claims"
    }
} catch {
    Test-Failure "Claims inspection" $_.Exception.Message
}

# ======================
# PHASE 3: REGRESSION
# ======================

Write-Host "`n--- PHASE 3: REGRESSION TESTS (Day 4) ---`n" -ForegroundColor Yellow

# Test 13: Password hashing
Write-Host "[Test 13] Password hashing still works" -ForegroundColor White
try {
    $slug3 = "hash-$(Get-Random -Minimum 1000 -Maximum 9999)"
    $body3 = @{
        tenantName = "Hash Test"
        tenantSlug = $slug3
        subscriptionPlan = "Free"
        adminEmail = "hash@test.com"
        adminPassword = "Password@123"
        adminFullName = "Hasher"
    } | ConvertTo-Json

    $reg3 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body3

    $loginBody3 = @{
        tenantSlug = $slug3
        email = "hash@test.com"
        password = "Password@123"
    } | ConvertTo-Json

    $login3 = Invoke-RestMethod -Uri "$baseUrl/api/auth/login" -Method Post -ContentType "application/json" -Body $loginBody3

    if ($login3.accessToken) {
        Test-Success "Password hashing working (Day 4 regression)"
    } else {
        Test-Failure "Password hashing" "Login failed"
    }
} catch {
    Test-Failure "Password hashing test" $_.Exception.Message
}

# Test 14: JWT authentication
Write-Host "`n[Test 14] JWT authentication still works" -ForegroundColor White
try {
    $jwtHeaders = @{ "Authorization" = "Bearer $rbacToken" }
    $jwtMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $jwtHeaders

    if ($jwtMe.userId) {
        Test-Success "JWT authentication working (Day 4 regression)"
    } else {
        Test-Failure "JWT authentication" "No user data"
    }
} catch {
    Test-Failure "JWT regression test" $_.Exception.Message
}

# ======================
# TEST SUMMARY
# ======================

Write-Host "`n================================================" -ForegroundColor Magenta
Write-Host "TEST EXECUTION SUMMARY" -ForegroundColor Magenta
Write-Host "================================================" -ForegroundColor Magenta

Write-Host "`nTotal Tests:  $testsTotal" -ForegroundColor White
Write-Host "Tests Passed: $testsPassed" -ForegroundColor Green
Write-Host "Tests Failed: $testsFailed" -ForegroundColor $(if ($testsFailed -eq 0) { "Green" } else { "Red" })

$passRate = if ($testsTotal -gt 0) { [math]::Round(($testsPassed / $testsTotal) * 100, 2) } else { 0 }
Write-Host "Pass Rate:    $passRate%" -ForegroundColor $(if ($passRate -ge 90) { "Green" } elseif ($passRate -ge 70) { "Yellow" } else { "Red" })

Write-Host "`n================================================" -ForegroundColor Magenta

if ($passRate -ge 95) {
    Write-Host "RESULT: EXCELLENT - Ready for production!" -ForegroundColor Green
    exit 0
} elseif ($passRate -ge 80) {
    Write-Host "RESULT: GOOD - Minor issues found" -ForegroundColor Yellow
    exit 1
} else {
    Write-Host "RESULT: CRITICAL - Major issues found!" -ForegroundColor Red
    exit 1
}
