<#
.SYNOPSIS
    KiCAD MCP Server - Windows Setup and Configuration Script

.DESCRIPTION
    This script automates the setup of KiCAD MCP Server on Windows by:
    - Detecting KiCAD installation and version
    - Verifying Python and Node.js installations
    - Testing KiCAD Python module (pcbnew)
    - Installing required Python dependencies
    - Building the TypeScript project
    - Generating Claude Desktop configuration
    - Running diagnostic tests

.PARAMETER SkipBuild
    Skip the npm build step (useful if already built)

.PARAMETER ClientType
    Type of MCP client to configure: 'claude-desktop', 'cline', or 'manual'
    Default: 'claude-desktop'

.EXAMPLE
    .\setup-windows.ps1
    Run the full setup with default options

.EXAMPLE
    .\setup-windows.ps1 -ClientType cline
    Setup for Cline VSCode extension

.EXAMPLE
    .\setup-windows.ps1 -SkipBuild
    Run setup without rebuilding the project
#>

param(
    [switch]$SkipBuild,
    [ValidateSet('claude-desktop', 'cline', 'manual')]
    [string]$ClientType = 'claude-desktop'
)

# Color output helpers
function Write-Success { param([string]$Message) Write-Host "[OK] $Message" -ForegroundColor Green }
function Write-Error-Custom { param([string]$Message) Write-Host "[ERROR] $Message" -ForegroundColor Red }
function Write-Warning-Custom { param([string]$Message) Write-Host "[WARN] $Message" -ForegroundColor Yellow }
function Write-Info { param([string]$Message) Write-Host "[INFO] $Message" -ForegroundColor Cyan }
function Write-Step { param([string]$Message) Write-Host "`n=== $Message ===" -ForegroundColor Magenta }

Write-Host @"
╔════════════════════════════════════════════════════════════╗
║         KiCAD MCP Server - Windows Setup Script           ║
║                                                            ║
║  This script will configure KiCAD MCP for Windows         ║
╚════════════════════════════════════════════════════════════╝
"@ -ForegroundColor Cyan

# Store results for final report
$script:Results = @{
    KiCADFound = $false
    KiCADVersion = ""
    KiCADPythonPath = ""
    PythonFound = $false
    PythonVersion = ""
    NodeFound = $false
    NodeVersion = ""
    PcbnewImport = $false
    DependenciesInstalled = $false
    ProjectBuilt = $false
    ConfigGenerated = $false
    Errors = @()
}

# Get script directory (project root)
$ProjectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path

Write-Step "Step 1: Detecting KiCAD Installation"

# Function to find KiCAD installation
function Find-KiCAD {
    $possiblePaths = @(
        "C:\Program Files\KiCad",
        "C:\Program Files (x86)\KiCad"
        "$env:USERPROFILE\AppData\Local\Programs\KiCad"
    )

    $versions = @("9.0", "9.1", "10.0", "8.0")

    foreach ($basePath in $possiblePaths) {
        foreach ($version in $versions) {
            $kicadPath = Join-Path $basePath $version
            $pythonExe = Join-Path $kicadPath "bin\python.exe"
            $pythonLib = Join-Path $kicadPath "lib\python3\dist-packages"

            if (Test-Path $pythonExe) {
                Write-Success "Found KiCAD $version at: $kicadPath"
                return @{
                    Path = $kicadPath
                    Version = $version
                    PythonExe = $pythonExe
                    PythonLib = $pythonLib
                }
            }
        }
    }

    return $null
}

$kicad = Find-KiCAD

if ($kicad) {
    $script:Results.KiCADFound = $true
    $script:Results.KiCADVersion = $kicad.Version
    $script:Results.KiCADPythonPath = $kicad.PythonLib
    Write-Info "KiCAD Version: $($kicad.Version)"
    Write-Info "Python Path: $($kicad.PythonLib)"
} else {
    Write-Error-Custom "KiCAD not found in standard locations"
    Write-Warning-Custom "Checked: C:\Program Files, C:\Program Files (x86), and $env:USERPROFILE\AppData\Local\Programs"
    Write-Warning-Custom "Please install KiCAD 9.0+ from https://www.kicad.org/download/windows/"
    $script:Results.Errors += "KiCAD not found"
}

Write-Step "Step 2: Checking Node.js Installation"

try {
    $nodeVersion = node --version 2>$null
    if ($LASTEXITCODE -eq 0) {
        Write-Success "Node.js found: $nodeVersion"
        $script:Results.NodeFound = $true
        $script:Results.NodeVersion = $nodeVersion

        # Check if version is 18+
        $versionNumber = [int]($nodeVersion -replace 'v(\d+)\..*', '$1')
        if ($versionNumber -lt 18) {
            Write-Warning-Custom "Node.js version 18+ is recommended (you have $nodeVersion)"
        }
    }
} catch {
    Write-Error-Custom "Node.js not found"
    Write-Warning-Custom "Please install Node.js 18+ from https://nodejs.org/"
    $script:Results.Errors += "Node.js not found"
}

Write-Step "Step 3: Testing KiCAD Python Module"

if ($kicad) {
    Write-Info "Testing pcbnew module import..."

    $testScript = "import sys; import pcbnew; print(f'SUCCESS:{pcbnew.GetBuildVersion()}')"
    $result = & $kicad.PythonExe -c $testScript 2>&1

    if ($result -match "SUCCESS:(.+)") {
        $pcbnewVersion = $matches[1]
        Write-Success "pcbnew module imported successfully: $pcbnewVersion"
        $script:Results.PcbnewImport = $true
    } else {
        Write-Error-Custom "Failed to import pcbnew module"
        Write-Warning-Custom "Error: $result"
        Write-Info "This usually means KiCAD was not installed with Python support"
        $script:Results.Errors += "pcbnew import failed: $result"
    }
} else {
    Write-Warning-Custom "Skipping pcbnew test (KiCAD not found)"
}

Write-Step "Step 4: Checking Python Installation"

try {
    $pythonVersion = python --version 2>&1
    if ($pythonVersion -match "Python (\d+\.\d+\.\d+)") {
        Write-Success "System Python found: $pythonVersion"
        $script:Results.PythonFound = $true
        $script:Results.PythonVersion = $pythonVersion
    }
} catch {
    Write-Warning-Custom "System Python not found (using KiCAD's Python)"
}

Write-Step "Step 5: Installing Node.js Dependencies"

if ($script:Results.NodeFound) {
    Write-Info "Running npm install..."
    Push-Location $ProjectRoot
    try {
        npm install 2>&1 | Out-Null
        if ($LASTEXITCODE -eq 0) {
            Write-Success "Node.js dependencies installed"
        } else {
            Write-Error-Custom "npm install failed"
            $script:Results.Errors += "npm install failed"
        }
    } finally {
        Pop-Location
    }
} else {
    Write-Warning-Custom "Skipping npm install (Node.js not found)"
}

Write-Step "Step 6: Installing Python Dependencies"

if ($kicad) {
    Write-Info "Installing Python packages..."
    Push-Location $ProjectRoot
    try {
        $requirementsFile = Join-Path $ProjectRoot "requirements.txt"
        if (Test-Path $requirementsFile) {
            & $kicad.PythonExe -m pip install -r $requirementsFile 2>&1 | Out-Null
            if ($LASTEXITCODE -eq 0) {
                Write-Success "Python dependencies installed"
                $script:Results.DependenciesInstalled = $true
            } else {
                Write-Warning-Custom "Some Python packages may have failed to install"
            }
        } else {
            Write-Warning-Custom "requirements.txt not found"
        }
    } finally {
        Pop-Location
    }
} else {
    Write-Warning-Custom "Skipping Python dependencies (KiCAD Python not found)"
}

Write-Step "Step 7: Building TypeScript Project"

if (-not $SkipBuild -and $script:Results.NodeFound) {
    Write-Info "Running npm run build..."
    Push-Location $ProjectRoot
    try {
        npm run build 2>&1 | Out-Null
        if ($LASTEXITCODE -eq 0) {
            $distPath = Join-Path $ProjectRoot "dist\index.js"
            if (Test-Path $distPath) {
                Write-Success "Project built successfully"
                $script:Results.ProjectBuilt = $true
            } else {
                Write-Error-Custom "Build completed but dist/index.js not found"
                $script:Results.Errors += "Build output missing"
            }
        } else {
            Write-Error-Custom "Build failed"
            $script:Results.Errors += "TypeScript build failed"
        }
    } finally {
        Pop-Location
    }
} else {
    if ($SkipBuild) {
        Write-Info "Skipping build (--SkipBuild specified)"
    } else {
        Write-Warning-Custom "Skipping build (Node.js not found)"
    }
}

Write-Step "Step 8: Generating Configuration"

if ($kicad -and $script:Results.ProjectBuilt) {
    $distPath = Join-Path $ProjectRoot "dist\index.js"
    $distPathEscaped = $distPath -replace '\\', '\\'
    $pythonLibEscaped = $kicad.PythonLib -replace '\\', '\\'

    $config = @"
{
  "mcpServers": {
    "kicad": {
      "command": "node",
      "args": ["$distPathEscaped"],
      "env": {
        "PYTHONPATH": "$pythonLibEscaped",
        "NODE_ENV": "production",
        "LOG_LEVEL": "info"
      }
    }
  }
}
"@

    $configPath = Join-Path $ProjectRoot "windows-mcp-config.json"
    $config | Out-File -FilePath $configPath -Encoding UTF8
    Write-Success "Configuration generated: $configPath"
    $script:Results.ConfigGenerated = $true

    Write-Info "`nConfiguration Preview:"
    Write-Host $config -ForegroundColor Gray

    # Provide instructions based on client type
    Write-Info "`nTo use this configuration:"

    if ($ClientType -eq 'claude-desktop') {
        $claudeConfigPath = "$env:APPDATA\Claude\claude_desktop_config.json"
        Write-Host "`n1. Open Claude Desktop configuration:" -ForegroundColor Yellow
        Write-Host "   $claudeConfigPath" -ForegroundColor White
        Write-Host "`n2. Copy the contents from:" -ForegroundColor Yellow
        Write-Host "   $configPath" -ForegroundColor White
        Write-Host "`n3. Restart Claude Desktop" -ForegroundColor Yellow
    } elseif ($ClientType -eq 'cline') {
        $clineConfigPath = "$env:APPDATA\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json"
        Write-Host "`n1. Open Cline configuration:" -ForegroundColor Yellow
        Write-Host "   $clineConfigPath" -ForegroundColor White
        Write-Host "`n2. Copy the contents from:" -ForegroundColor Yellow
        Write-Host "   $configPath" -ForegroundColor White
        Write-Host "`n3. Restart VSCode" -ForegroundColor Yellow
    } else {
        Write-Host "`n1. Configuration saved to:" -ForegroundColor Yellow
        Write-Host "   $configPath" -ForegroundColor White
        Write-Host "`n2. Copy to your MCP client configuration" -ForegroundColor Yellow
    }

} else {
    Write-Warning-Custom "Skipping configuration generation (prerequisites not met)"
}

Write-Step "Step 9: Running Diagnostic Test"

if ($kicad -and $script:Results.ProjectBuilt) {
    Write-Info "Testing server startup..."

    $env:PYTHONPATH = $kicad.PythonLib
    $distPath = Join-Path $ProjectRoot "dist\index.js"

    # Start the server process
    $process = Start-Process -FilePath "node" `
                            -ArgumentList $distPath `
                            -NoNewWindow `
                            -PassThru `
                            -RedirectStandardError (Join-Path $env:TEMP "kicad-mcp-test-error.txt") `
                            -RedirectStandardOutput (Join-Path $env:TEMP "kicad-mcp-test-output.txt")

    # Wait a moment for startup
    Start-Sleep -Seconds 2

    if (-not $process.HasExited) {
        Write-Success "Server started successfully (PID: $($process.Id))"
        Write-Info "Stopping test server..."
        Stop-Process -Id $process.Id -Force
    } else {
        Write-Error-Custom "Server exited immediately (exit code: $($process.ExitCode))"

        $errorLog = Join-Path $env:TEMP "kicad-mcp-test-error.txt"
        if (Test-Path $errorLog) {
            $errorContent = Get-Content $errorLog -Raw
            if ($errorContent) {
                Write-Warning-Custom "Error output:"
                Write-Host $errorContent -ForegroundColor Red
            }
        }

        $script:Results.Errors += "Server startup test failed"
    }
} else {
    Write-Warning-Custom "Skipping diagnostic test (prerequisites not met)"
}

# Final Report
Write-Step "Setup Summary"

Write-Host "`nComponent Status:" -ForegroundColor Cyan
Write-Host "  KiCAD Installation:     $(if ($script:Results.KiCADFound) { '[OK] Found' } else { '[ERROR] Not Found' })" -ForegroundColor $(if ($script:Results.KiCADFound) { 'Green' } else { 'Red' })
if ($script:Results.KiCADVersion) {
    Write-Host "    Version:              $($script:Results.KiCADVersion)" -ForegroundColor Gray
}
Write-Host "  pcbnew Module:          $(if ($script:Results.PcbnewImport) { '[OK] Working' } else { '[ERROR] Failed' })" -ForegroundColor $(if ($script:Results.PcbnewImport) { 'Green' } else { 'Red' })
Write-Host "  Node.js:                $(if ($script:Results.NodeFound) { '[OK] Found' } else { '[ERROR] Not Found' })" -ForegroundColor $(if ($script:Results.NodeFound) { 'Green' } else { 'Red' })
if ($script:Results.NodeVersion) {
    Write-Host "    Version:              $($script:Results.NodeVersion)" -ForegroundColor Gray
}
Write-Host "  Python Dependencies:    $(if ($script:Results.DependenciesInstalled) { '[OK] Installed' } else { '[ERROR] Failed' })" -ForegroundColor $(if ($script:Results.DependenciesInstalled) { 'Green' } else { 'Red' })
Write-Host "  Project Build:          $(if ($script:Results.ProjectBuilt) { '[OK] Success' } else { '[ERROR] Failed' })" -ForegroundColor $(if ($script:Results.ProjectBuilt) { 'Green' } else { 'Red' })
Write-Host "  Configuration:          $(if ($script:Results.ConfigGenerated) { '[OK] Generated' } else { '[ERROR] Not Generated' })" -ForegroundColor $(if ($script:Results.ConfigGenerated) { 'Green' } else { 'Red' })

if ($script:Results.Errors.Count -gt 0) {
    Write-Host "`nErrors Encountered:" -ForegroundColor Red
    foreach ($error in $script:Results.Errors) {
        Write-Host "  • $error" -ForegroundColor Red
    }
}

# Check for log file
$logPath = "$env:USERPROFILE\.kicad-mcp\logs\kicad_interface.log"
if (Test-Path $logPath) {
    Write-Host "`nLog file location:" -ForegroundColor Cyan
    Write-Host "  $logPath" -ForegroundColor Gray
}

# Success criteria
$isSuccess = $script:Results.KiCADFound -and
             $script:Results.PcbnewImport -and
             $script:Results.NodeFound -and
             $script:Results.ProjectBuilt

if ($isSuccess) {
    Write-Host "`n============================================================" -ForegroundColor Green
    Write-Host "  [OK] Setup completed successfully!" -ForegroundColor Green
    Write-Host "" -ForegroundColor Green
    Write-Host "  Next steps:" -ForegroundColor Green
    Write-Host "  1. Copy the generated config to your MCP client" -ForegroundColor Green
    Write-Host "  2. Restart your MCP client (Claude Desktop/Cline)" -ForegroundColor Green
    Write-Host "  3. Try: 'Create a new KiCAD project'" -ForegroundColor Green
    Write-Host "============================================================" -ForegroundColor Green
} else {
    Write-Host "`n============================================================" -ForegroundColor Red
    Write-Host "  [ERROR] Setup incomplete - issues detected" -ForegroundColor Red
    Write-Host "" -ForegroundColor Red
    Write-Host "  Please resolve the errors above and run again" -ForegroundColor Red
    Write-Host "" -ForegroundColor Red
    Write-Host "  For help:" -ForegroundColor Red
    Write-Host "  https://github.com/mixelpixx/KiCAD-MCP-Server/issues" -ForegroundColor Red
    Write-Host "============================================================" -ForegroundColor Red
    exit 1
}
