# CCS Custom Claude CLI Path - Comprehensive Test Suite
# Tests CCS_CLAUDE_PATH environment variable support (v2.3.0)
# Windows PowerShell 5.1+ compatible

param(
    [switch]$Verbose,
    [switch]$QuickTest  # Skip slow tests
)

$ErrorActionPreference = "Stop"

# --- Test Framework ---

$Script:TotalTests = 0
$Script:PassedTests = 0
$Script:FailedTests = 0
$Script:SkippedTests = 0
$Script:StartTime = Get-Date
$Script:TestResults = @()

function Write-TestHeader {
    param([string]$Category)
    Write-Host "`n========================================" -ForegroundColor Cyan
    Write-Host "  $Category" -ForegroundColor Cyan
    Write-Host "========================================`n" -ForegroundColor Cyan
}

function Write-TestResult {
    param(
        [string]$TestName,
        [string]$Status,  # PASS, FAIL, SKIP
        [string]$Details = "",
        [int]$DurationMs = 0
    )

    $Script:TotalTests++

    $Symbol = switch ($Status) {
        "PASS" { "[OK]"; $Script:PassedTests++; $Color = "Green" }
        "FAIL" { "[X]"; $Script:FailedTests++; $Color = "Red" }
        "SKIP" { "[i]"; $Script:SkippedTests++; $Color = "Yellow" }
    }

    Write-Host "$Symbol $TestName" -ForegroundColor $Color
    if ($Details) {
        Write-Host "    $Details" -ForegroundColor Gray
    }
    if ($DurationMs -gt 0) {
        Write-Host "    Duration: ${DurationMs}ms" -ForegroundColor Gray
    }

    $Script:TestResults += [PSCustomObject]@{
        TestName = $TestName
        Status = $Status
        Details = $Details
        DurationMs = $DurationMs
    }
}

# --- Test Environment Setup ---

$Script:TestDir = "$env:TEMP\ccs-test-$(Get-Random)"
$Script:MockClaudeDir = Join-Path $TestDir "mock-claude"
$Script:OriginalEnv = @{
    CCS_CLAUDE_PATH = $env:CCS_CLAUDE_PATH
    PATH = $env:PATH
}

function Initialize-TestEnvironment {
    Write-Host "`n[Initializing Test Environment]" -ForegroundColor Cyan
    Write-Host "  Test Directory: $Script:TestDir"

    # Create test directories
    New-Item -ItemType Directory -Path $Script:TestDir -Force | Out-Null
    New-Item -ItemType Directory -Path $Script:MockClaudeDir -Force | Out-Null

    # Create mock claude.exe (simple executable that returns version)
    $MockExePath = Join-Path $Script:MockClaudeDir "claude.exe"

    # PowerShell script wrapped as executable
    $MockScript = @'
# Mock Claude CLI
Write-Host "Mock Claude CLI v1.0.0"
exit 0
'@

    # Create a batch file that calls PowerShell (simplest executable)
    $BatchContent = @"
@echo off
echo Mock Claude CLI v1.0.0
exit /b 0
"@

    Set-Content -Path $MockExePath -Value $BatchContent -Force

    Write-Host "  [OK] Created mock claude.exe at $MockExePath" -ForegroundColor Green
    Write-Host ""
}

function Restore-TestEnvironment {
    Write-Host "`n[Cleaning Up Test Environment]" -ForegroundColor Cyan

    # Restore original environment variables
    $env:CCS_CLAUDE_PATH = $Script:OriginalEnv.CCS_CLAUDE_PATH
    $env:PATH = $Script:OriginalEnv.PATH

    # Remove test directory
    if (Test-Path $Script:TestDir) {
        Remove-Item -Path $Script:TestDir -Recurse -Force -ErrorAction SilentlyContinue
        Write-Host "  [OK] Removed test directory" -ForegroundColor Green
    }

    Write-Host ""
}

# --- Helper Functions ---

function Get-CcsPath {
    # Try to find CCS in multiple locations
    $PossiblePaths = @(
        "$env:USERPROFILE\.ccs\ccs.ps1",  # Installed location
        (Join-Path (Split-Path -Parent (Split-Path -Parent $PSCommandPath)) "ccs.ps1"),  # Repo location
        (Get-Command ccs -ErrorAction SilentlyContinue).Source  # From PATH
    )

    foreach ($Path in $PossiblePaths) {
        if ($Path -and (Test-Path $Path)) {
            return $Path
        }
    }

    throw "CCS script not found. Checked: $($PossiblePaths -join ', ')"
}

function Test-ClaudeDetection {
    param(
        [string]$ExpectedPath = "",
        [bool]$ShouldSucceed = $true
    )

    $CcsPath = Get-CcsPath

    try {
        # Extract Find-ClaudeCli function and test it
        $CcsContent = Get-Content $CcsPath -Raw

        # Execute detection logic in isolated scope
        $DetectionScript = {
            param($CcsContent, $TestEnv)

            # Set up test environment
            foreach ($key in $TestEnv.Keys) {
                Set-Item -Path "env:$key" -Value $TestEnv[$key]
            }

            # Extract and execute Find-ClaudeCli function
            $FunctionStart = $CcsContent.IndexOf("function Find-ClaudeCli {")
            $FunctionEnd = $CcsContent.IndexOf("`n}", $FunctionStart) + 2
            $Function = $CcsContent.Substring($FunctionStart, $FunctionEnd - $FunctionStart)

            Invoke-Expression $Function

            return Find-ClaudeCli
        }

        $TestEnv = @{
            CCS_CLAUDE_PATH = $env:CCS_CLAUDE_PATH
            PATH = $env:PATH
        }

        $Result = & $DetectionScript -CcsContent $CcsContent -TestEnv $TestEnv

        if ($ShouldSucceed) {
            if ([string]::IsNullOrEmpty($Result)) {
                throw "Detection failed: No path returned"
            }
            if ($ExpectedPath -and ($Result -ne $ExpectedPath)) {
                throw "Detection returned wrong path: $Result (expected: $ExpectedPath)"
            }
            return $Result
        } else {
            if (-not [string]::IsNullOrEmpty($Result)) {
                throw "Detection should have failed but returned: $Result"
            }
            return ""
        }
    } catch {
        if ($ShouldSucceed) {
            throw $_
        }
        return ""
    }
}

function Get-MockClaudePath {
    return Join-Path $Script:MockClaudeDir "claude.exe"
}

# --- Test Category 1: Environment Variable Detection (Priority 1) ---

function Test-Category1-EnvVarDetection {
    Write-TestHeader "Category 1: Environment Variable Detection (Priority 1)"

    # Test 1.1: Valid CCS_CLAUDE_PATH
    $TestStart = Get-Date
    try {
        $MockPath = Get-MockClaudePath
        $env:CCS_CLAUDE_PATH = $MockPath

        $DetectedPath = Test-ClaudeDetection -ExpectedPath $MockPath -ShouldSucceed $true

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.1: Valid CCS_CLAUDE_PATH" `
            -Status "PASS" `
            -Details "Detected: $DetectedPath" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.1: Valid CCS_CLAUDE_PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 1.2: Invalid CCS_CLAUDE_PATH (non-existent file)
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = "D:\nonexistent\claude.exe"

        # Should fall back to PATH or common locations
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.2: Invalid CCS_CLAUDE_PATH (non-existent)" `
            -Status "PASS" `
            -Details "Correctly fell back to search" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.2: Invalid CCS_CLAUDE_PATH (non-existent)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 1.3: CCS_CLAUDE_PATH is a directory (not file)
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $Script:TestDir

        # Should fail validation and fall back
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.3: CCS_CLAUDE_PATH is directory" `
            -Status "PASS" `
            -Details "Validation correctly rejected directory" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.3: CCS_CLAUDE_PATH is directory" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 1.4: CCS_CLAUDE_PATH with special characters (spaces)
    $TestStart = Get-Date
    try {
        # Create mock in path with spaces
        $SpacePath = Join-Path $Script:TestDir "Program Files (x86)"
        New-Item -ItemType Directory -Path $SpacePath -Force | Out-Null
        $SpaceClaudePath = Join-Path $SpacePath "claude.exe"
        Copy-Item (Get-MockClaudePath) $SpaceClaudePath -Force

        $env:CCS_CLAUDE_PATH = $SpaceClaudePath

        $DetectedPath = Test-ClaudeDetection -ExpectedPath $SpaceClaudePath -ShouldSucceed $true

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.4: CCS_CLAUDE_PATH with spaces" `
            -Status "PASS" `
            -Details "Handled spaces correctly" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 1.4: CCS_CLAUDE_PATH with spaces" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }
}

# --- Test Category 2: PATH Detection (Priority 2) ---

function Test-Category2-PathDetection {
    Write-TestHeader "Category 2: PATH Detection (Priority 2)"

    # Test 2.1: Claude in PATH
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null
        $MockPath = Get-MockClaudePath
        $env:PATH = "$Script:MockClaudeDir;$env:PATH"

        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $true

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 2.1: Claude in PATH" `
            -Status "PASS" `
            -Details "Found via PATH: $DetectedPath" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 2.1: Claude in PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:PATH = $Script:OriginalEnv.PATH
    }

    # Test 2.2: No CCS_CLAUDE_PATH, no PATH
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null
        # Keep original PATH (no mock claude in it)

        # Should fall back to common locations (will fail in test environment)
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 2.2: No CCS_CLAUDE_PATH, no PATH" `
            -Status "PASS" `
            -Details "Correctly fell back to Priority 3" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 2.2: No CCS_CLAUDE_PATH, no PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }
}

# --- Test Category 3: Common Locations (Priority 3) ---

function Test-Category3-CommonLocations {
    Write-TestHeader "Category 3: Common Locations (Priority 3)"

    # Test 3.1: Claude in C:\Program Files
    $TestStart = Get-Date
    try {
        if ($QuickTest) {
            Write-TestResult -TestName "Test 3.1: Claude in C:\Program Files" `
                -Status "SKIP" `
                -Details "Skipped in quick test mode"
        } else {
            # This test requires admin rights to create in C:\Program Files
            Write-TestResult -TestName "Test 3.1: Claude in C:\Program Files" `
                -Status "SKIP" `
                -Details "Requires admin rights to test"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 3.1: Claude in C:\Program Files" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }

    # Test 3.2: Claude on D drive
    $TestStart = Get-Date
    try {
        if ($QuickTest) {
            Write-TestResult -TestName "Test 3.2: Claude on D drive" `
                -Status "SKIP" `
                -Details "Skipped in quick test mode"
        } else {
            # This test requires D: drive to exist
            if (Test-Path "D:\") {
                Write-TestResult -TestName "Test 3.2: Claude on D drive" `
                    -Status "SKIP" `
                    -Details "Requires D: drive setup"
            } else {
                Write-TestResult -TestName "Test 3.2: Claude on D drive" `
                    -Status "SKIP" `
                    -Details "D: drive not available"
            }
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 3.2: Claude on D drive" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }

    # Test 3.3: Claude not found anywhere
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null
        $env:PATH = $Script:OriginalEnv.PATH

        # Remove mock from PATH, should fail to find anywhere
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 3.3: Claude not found anywhere" `
            -Status "PASS" `
            -Details "Correctly returned empty when not found" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 3.3: Claude not found anywhere" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }
}

# --- Test Category 4: Security Validation ---

function Test-Category4-SecurityValidation {
    Write-TestHeader "Category 4: Security Validation"

    # Test 4.1: Command injection attempt (semicolon)
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = "claude.exe; rm -rf /"

        # Should be rejected by character validation
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.1: Injection attempt (semicolon)" `
            -Status "PASS" `
            -Details "Blocked semicolon character" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.1: Injection attempt (semicolon)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 4.2: Command injection attempt (pipe)
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = "claude.exe | malicious.exe"

        # Should be rejected by character validation
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.2: Injection attempt (pipe)" `
            -Status "PASS" `
            -Details "Blocked pipe character" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.2: Injection attempt (pipe)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 4.3: Command injection attempt (backtick)
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = "claude.exe`nmalicious.exe"

        # Should be rejected by character validation
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.3: Injection attempt (backtick)" `
            -Status "PASS" `
            -Details "Blocked backtick/newline" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.3: Injection attempt (backtick)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 4.4: Path traversal attempt
    $TestStart = Get-Date
    try {
        # Relative paths should be allowed (valid use case)
        $RelativePath = "..\..\Windows\System32\cmd.exe"
        $env:CCS_CLAUDE_PATH = $RelativePath

        # Should resolve to absolute path and validate
        # Will fail on non-executable, but path format is OK
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.4: Path traversal (relative paths OK)" `
            -Status "PASS" `
            -Details "Relative paths allowed, validation on file type" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 4.4: Path traversal (relative paths OK)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }
}

# --- Test Category 5: Error Messages ---

function Test-Category5-ErrorMessages {
    Write-TestHeader "Category 5: Error Messages"

    # Test 5.1: Error message completeness
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null
        $env:PATH = $Script:OriginalEnv.PATH

        # Capture error output
        $CcsPath = Get-CcsPath

        $ErrorOutput = & $CcsPath --help 2>&1 | Out-String

        # Check for required sections in error message
        $HasCcsClaudePathStatus = $ErrorOutput -match "CCS_CLAUDE_PATH:"
        $HasPathSearch = $ErrorOutput -match "System PATH:"
        $HasCommonLocations = $ErrorOutput -match "Common locations:"
        $HasSolutions = $ErrorOutput -match "Solutions:"
        $HasDebugging = $ErrorOutput -match "Debugging:"

        $AllSectionsPresent = $HasCcsClaudePathStatus -and $HasPathSearch -and
                              $HasCommonLocations -and $HasSolutions -and $HasDebugging

        if ($AllSectionsPresent) {
            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 5.1: Error message completeness" `
                -Status "PASS" `
                -Details "All required sections present" `
                -DurationMs $Duration
        } else {
            throw "Missing sections in error message"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 5.1: Error message completeness" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }

    # Test 5.2: Error message D drive examples
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null
        $env:PATH = $Script:OriginalEnv.PATH

        $CcsPath = Get-CcsPath

        $ErrorOutput = & $CcsPath --help 2>&1 | Out-String

        $HasDDriveExample = $ErrorOutput -match "D:"

        if ($HasDDriveExample) {
            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 5.2: Error message D drive examples" `
                -Status "PASS" `
                -Details "D: drive examples present" `
                -DurationMs $Duration
        } else {
            throw "D: drive examples missing"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 5.2: Error message D drive examples" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }
}

# --- Test Category 6: Integration Tests ---

function Test-Category6-Integration {
    Write-TestHeader "Category 6: Integration Tests"

    # Test 6.1: Full workflow with CCS_CLAUDE_PATH
    $TestStart = Get-Date
    try {
        $MockPath = Get-MockClaudePath
        $env:CCS_CLAUDE_PATH = $MockPath

        $CcsPath = Get-CcsPath

        # Run ccs with mock claude (will fail on config but detection should work)
        $Output = & $CcsPath --help 2>&1 | Out-String

        # Check if it used the custom Claude path (not error about not finding)
        $UsedCustomPath = -not ($Output -match "Claude CLI not found")

        if ($UsedCustomPath) {
            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 6.1: Full workflow with CCS_CLAUDE_PATH" `
                -Status "PASS" `
                -Details "Used custom Claude path successfully" `
                -DurationMs $Duration
        } else {
            throw "Did not use custom Claude path"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 6.1: Full workflow with CCS_CLAUDE_PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 6.2: Version command bypasses detection
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null

        $CcsPath = Get-CcsPath

        $Output = & $CcsPath --version 2>&1 | Out-String

        $ShowsVersion = $Output -match "CCS \(Claude Code Switch\) version"

        if ($ShowsVersion) {
            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 6.2: Version command bypasses detection" `
                -Status "PASS" `
                -Details "Version shown without Claude detection" `
                -DurationMs $Duration
        } else {
            throw "Version command failed"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 6.2: Version command bypasses detection" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }

    # Test 6.3: Help command uses detection
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = $null

        $CcsPath = Get-CcsPath

        $Output = & $CcsPath --help 2>&1 | Out-String

        $TriedDetection = $Output -match "Claude CLI not found"

        if ($TriedDetection) {
            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 6.3: Help command uses detection" `
                -Status "PASS" `
                -Details "Help command triggered Claude detection" `
                -DurationMs $Duration
        } else {
            throw "Help command did not trigger detection"
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 6.3: Help command uses detection" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    }
}

# --- Test Category 7: Edge Cases ---

function Test-Category7-EdgeCases {
    Write-TestHeader "Category 7: Edge Cases"

    # Test 7.1: Empty CCS_CLAUDE_PATH
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = ""

        # Should treat as unset and continue fallback
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.1: Empty CCS_CLAUDE_PATH" `
            -Status "PASS" `
            -Details "Treated as unset, continued fallback" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.1: Empty CCS_CLAUDE_PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 7.2: Whitespace-only CCS_CLAUDE_PATH
    $TestStart = Get-Date
    try {
        $env:CCS_CLAUDE_PATH = "   "

        # Should fail validation and continue fallback
        $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.2: Whitespace-only CCS_CLAUDE_PATH" `
            -Status "PASS" `
            -Details "Validation failed, continued fallback" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.2: Whitespace-only CCS_CLAUDE_PATH" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 7.3: Very long path (>260 characters)
    $TestStart = Get-Date
    try {
        if ($QuickTest) {
            Write-TestResult -TestName "Test 7.3: Very long path (>260 chars)" `
                -Status "SKIP" `
                -Details "Skipped in quick test mode"
        } else {
            # Create a path longer than 260 characters
            $LongPath = "C:\" + ("very-long-directory-name\" * 20) + "claude.exe"
            $env:CCS_CLAUDE_PATH = $LongPath

            # Should handle long paths (may fail on file not found, not path length)
            $DetectedPath = Test-ClaudeDetection -ShouldSucceed $false

            $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
            Write-TestResult -TestName "Test 7.3: Very long path (>260 chars)" `
                -Status "PASS" `
                -Details "Handled long path without crash" `
                -DurationMs $Duration
        }
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.3: Very long path (>260 chars)" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }

    # Test 7.4: Unicode in path
    $TestStart = Get-Date
    try {
        # Create directory with Unicode characters
        $UnicodePath = Join-Path $Script:TestDir "文件夹"
        New-Item -ItemType Directory -Path $UnicodePath -Force | Out-Null
        $UnicodeClaudePath = Join-Path $UnicodePath "claude.exe"
        Copy-Item (Get-MockClaudePath) $UnicodeClaudePath -Force

        $env:CCS_CLAUDE_PATH = $UnicodeClaudePath

        $DetectedPath = Test-ClaudeDetection -ExpectedPath $UnicodeClaudePath -ShouldSucceed $true

        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.4: Unicode in path" `
            -Status "PASS" `
            -Details "Handled Unicode characters correctly" `
            -DurationMs $Duration
    } catch {
        $Duration = ((Get-Date) - $TestStart).TotalMilliseconds
        Write-TestResult -TestName "Test 7.4: Unicode in path" `
            -Status "FAIL" `
            -Details $_.Exception.Message `
            -DurationMs $Duration
    } finally {
        $env:CCS_CLAUDE_PATH = $null
    }
}

# --- Main Execution ---

function Show-TestSummary {
    $EndTime = Get-Date
    $TotalDuration = ($EndTime - $Script:StartTime).TotalSeconds

    Write-Host "`n========================================" -ForegroundColor Cyan
    Write-Host "  TEST SUMMARY" -ForegroundColor Cyan
    Write-Host "========================================`n" -ForegroundColor Cyan

    Write-Host "Total Tests:   $Script:TotalTests"
    Write-Host "Passed:        $Script:PassedTests" -ForegroundColor Green
    Write-Host "Failed:        $Script:FailedTests" -ForegroundColor Red
    Write-Host "Skipped:       $Script:SkippedTests" -ForegroundColor Yellow

    $PassRate = if ($Script:TotalTests -gt 0) {
        [math]::Round(($Script:PassedTests / $Script:TotalTests) * 100, 2)
    } else {
        0
    }
    Write-Host "Pass Rate:     $PassRate%"
    Write-Host "Duration:      ${TotalDuration}s"

    Write-Host "`n"

    # Show failures
    if ($Script:FailedTests -gt 0) {
        Write-Host "FAILED TESTS:" -ForegroundColor Red
        $Script:TestResults | Where-Object { $_.Status -eq "FAIL" } | ForEach-Object {
            Write-Host "  - $($_.TestName)" -ForegroundColor Red
            Write-Host "    $($_.Details)" -ForegroundColor Gray
        }
        Write-Host "`n"
    }

    # Exit code
    if ($Script:FailedTests -gt 0) {
        exit 1
    } else {
        exit 0
    }
}

# --- Run Tests ---

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "  CCS Custom Claude CLI Path Test Suite" -ForegroundColor Cyan
Write-Host "  Version: 2.3.0" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan

Initialize-TestEnvironment

try {
    Test-Category1-EnvVarDetection
    Test-Category2-PathDetection
    Test-Category3-CommonLocations
    Test-Category4-SecurityValidation
    Test-Category5-ErrorMessages
    Test-Category6-Integration
    Test-Category7-EdgeCases

    Show-TestSummary
} finally {
    Restore-TestEnvironment
}
