<#
.SYNOPSIS
    Downloads and installs the Gitea Tea CLI tool for Windows.

.DESCRIPTION
    This script automatically downloads, verifies, and installs the Tea CLI (Gitea command-line tool).
    It supports automatic detection of the latest version, SHA256 checksum verification, and intelligent
    installation location based on administrator privileges.

.PARAMETER TeaVersion
    Specifies the version of Tea to install. If not provided, the script will automatically fetch
    the latest version from the Gitea releases page.

.PARAMETER Force
    Bypasses the overwrite confirmation prompt if Tea is already installed.

.EXAMPLE
    .\download-tea.ps1
    Automatically detects and installs the latest version of Tea.

.EXAMPLE
    .\download-tea.ps1 -TeaVersion "0.11.1"
    Installs a specific version of Tea (v0.11.1).

.EXAMPLE
    .\download-tea.ps1 -Force
    Installs the latest version and overwrites any existing installation without prompting.

.EXAMPLE
    .\download-tea.ps1 -TeaVersion "0.11.1" -Force
    Installs version 0.11.1 and overwrites existing installation without prompting.

.NOTES
    - Requires internet connection to download from https://gitea.com
    - Automatically detects system architecture (AMD64 or 386)
    - Installation location:
      * With Admin rights: C:\Program Files\tea
      * Without Admin rights: %LOCALAPPDATA%\Programs\tea
    - Automatically updates PATH environment variable
    - After installation, restart your terminal or reload PATH with:
      $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine")

.LINK
    https://gitea.com/gitea/tea
#>

# Parameters
param(
  [string]$TeaVersion,
  [switch]$Force
)

# 1. Determine version to install
if (-not $TeaVersion) {
  Write-Host "No version specified. Fetching latest release..."
  try {
    # Fetch the releases page and parse HTML to find the latest version
    $releasePage = Invoke-WebRequest -Uri "https://gitea.com/gitea/tea/releases" -UseBasicParsing -ErrorAction Stop
    # Parse the HTML to find the latest version tag (format: /gitea/tea/releases/tag/v0.x.x)
    if ($releasePage.Content -match '/gitea/tea/releases/tag/v([\d.]+)') {
      $TeaVersion = $matches[1]
      Write-Host "Latest version found: v$TeaVersion" -ForegroundColor Green
    }
    else {
      Write-Error "Could not determine the latest version from the releases page."
      Write-Host "Please specify a version manually using -TeaVersion parameter."
      exit 1
    }
  }
  catch {
    Write-Error "Failed to fetch latest version: $($_.Exception.Message)"
    Write-Host "Please specify a version manually using -TeaVersion parameter."
    exit 1
  }
}
else {
  Write-Host "Using specified version: v$TeaVersion"
}

# 2. Define variables for the download
# Detect system architecture (AMD64 = 64-bit, 386 = 32-bit)
$Architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { "amd64" } else { "386" }

# Construct download URLs
$DownloadUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/tea-$TeaVersion-windows-$Architecture.exe"
$ChecksumUrl = "https://gitea.com/gitea/tea/releases/download/v$TeaVersion/checksums.txt"

# Determine installation directory based on admin privileges
# Admin: Install to Program Files (system-wide)
# Non-Admin: Install to user's AppData (user-specific)
$IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
$InstallDir = if ($IsAdmin) { "C:\Program Files\tea" } else { "$env:LOCALAPPDATA\Programs\tea" }

# Define file names and temp locations
$FileName = "tea.exe"
$TempFile = "$env:TEMP\tea-$TeaVersion.exe"
$TempChecksum = "$env:TEMP\tea-checksums.txt"

# 3. Check if file already exists
if ((Test-Path -Path "$InstallDir\$FileName") -and -not $Force) {
  # Prompt user before overwriting existing installation
  $response = Read-Host "tea.exe already exists in $InstallDir. Overwrite? (Y/N)"
  if ($response -ne 'Y' -and $response -ne 'y') {
    Write-Host "Installation cancelled."
    exit 0
  }
}

# 4. Create the installation directory if it doesn't exist
Write-Host "Creating installation directory: $InstallDir"
if (-not (Test-Path -Path $InstallDir)) {
  New-Item -Path $InstallDir -ItemType Directory -Force | Out-Null
}

# 5. Download the binary and checksum
Write-Host "Downloading tea CLI v$TeaVersion for $Architecture..."
try {
  # Download to temp location first for safety
  Invoke-WebRequest -Uri $DownloadUrl -OutFile $TempFile -UseBasicParsing -ErrorAction Stop
  Write-Host "Binary downloaded successfully."
}
catch {
  Write-Error "Failed to download the file. Please check the URL and version number. Error: $($_.Exception.Message)"
  # Cleanup temp files on failure
  Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
  exit 1
}

# Try to download checksum file for verification (optional but recommended)
$checksumAvailable = $false
try {
  Write-Host "Attempting to download checksum file..."
  Invoke-WebRequest -Uri $ChecksumUrl -OutFile $TempChecksum -UseBasicParsing -ErrorAction Stop
  $checksumAvailable = $true
  Write-Host "Checksum file downloaded."
}
catch {
  Write-Warning "Checksum file not available for this version. Skipping verification."
}

# 6. Verify checksum (if available)
if ($checksumAvailable) {
  Write-Host "Verifying file integrity..."
  try {
    # Calculate SHA256 hash of downloaded file
    $downloadedHash = (Get-FileHash -Path $TempFile -Algorithm SHA256).Hash.ToLower()
    
    # Parse checksums.txt to find the hash for our specific file
    $expectedFileName = "tea-$TeaVersion-windows-$Architecture.exe"
    $checksumContent = Get-Content -Path $TempChecksum -Raw
    $expectedHash = $null
    
    # checksums.txt format is: "hash  filename"
    foreach ($line in ($checksumContent -split "`n")) {
      if ($line -match "^([a-fA-F0-9]+)\s+$expectedFileName") {
        $expectedHash = $matches[1].ToLower()
        break
      }
    }
    
    if (-not $expectedHash) {
      Write-Warning "Could not find checksum for $expectedFileName in checksums.txt"
      $response = Read-Host "Continue without checksum verification? (Y/N)"
      if ($response -ne 'Y' -and $response -ne 'y') {
        Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
        Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
        exit 1
      }
    }
    elseif ($downloadedHash -eq $expectedHash) {
      Write-Host "Checksum verification passed." -ForegroundColor Green
    }
    else {
      Write-Error "Checksum verification failed! Downloaded file may be corrupted or tampered with."
      Write-Error "Expected: $expectedHash"
      Write-Error "Got: $downloadedHash"
      Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
      Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
      exit 1
    }
  }
  catch {
    Write-Warning "Could not verify checksum: $($_.Exception.Message)"
    $response = Read-Host "Continue without checksum verification? (Y/N)"
    if ($response -ne 'Y' -and $response -ne 'y') {
      Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
      Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
      exit 1
    }
  }
}

# 7. Move file to installation directory
try {
  Move-Item -Path $TempFile -Destination "$InstallDir\$FileName" -Force -ErrorAction Stop
  Write-Host "Installed to $InstallDir\$FileName"
  # Cleanup checksum file after successful installation
  Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
}
catch {
  Write-Error "Failed to move file to installation directory: $($_.Exception.Message)"
  Remove-Item -Path $TempFile -ErrorAction SilentlyContinue
  Remove-Item -Path $TempChecksum -ErrorAction SilentlyContinue
  exit 1
}

# 8. Add the directory to PATH
Write-Host ""
Write-Host "Updating PATH environment variable..."
try {
  # Try Machine (system-wide) PATH first - requires Administrator privileges
  $machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine")
  if ($machinePath -notlike "*$InstallDir*") {
    [Environment]::SetEnvironmentVariable("Path", "$machinePath;$InstallDir", "Machine")
    Write-Host "Added to system PATH (Machine level)." -ForegroundColor Green
    Write-Host "You may need to restart your terminal for changes to take effect."
  }
  else {
    Write-Host "Directory is already in system PATH."
  }
}
catch {
  Write-Warning "Could not modify System PATH (requires Administrator rights)."
  Write-Host "Attempting to add to User PATH instead..."
  
  # Fallback to User PATH - doesn't require Administrator privileges
  try {
    $userPath = [Environment]::GetEnvironmentVariable("Path", "User")
    if ($userPath -notlike "*$InstallDir*") {
      [Environment]::SetEnvironmentVariable("Path", "$userPath;$InstallDir", "User")
      Write-Host "Added to User PATH." -ForegroundColor Green
      Write-Host "You may need to restart your terminal for changes to take effect."
    }
    else {
      Write-Host "Directory is already in User PATH."
    }
  }
  catch {
    Write-Warning "Could not modify User PATH either. You may need to add '$InstallDir' to your PATH manually."
  }
}

# 9. Verification
Write-Host ""
Write-Host "Verification:"
try {
  # Test the installation by running tea --version
  $version = & "$InstallDir\$FileName" --version 2>&1
  Write-Host $version -ForegroundColor Green
}
catch {
  Write-Warning "Could not execute tea. PATH may not be updated in this session."
}

Write-Host ""
Write-Host "Installation complete! Run 'tea login add' to start configuring your Gitea instance." -ForegroundColor Cyan
Write-Host "Note: If 'tea' command is not found, restart your terminal or reload PATH with:" -ForegroundColor Yellow
Write-Host '  $env:Path = [System.Environment]::GetEnvironmentVariable("Path","User") + ";" + [System.Environment]::GetEnvironmentVariable("Path","Machine")' -ForegroundColor Gray