# PCode Windows PowerShell Shared Utilities
# Common functions for check.ps1 and install.ps1

function Get-DependencyStatus {
    <#
    .SYNOPSIS
    Checks if a command is available and gets its version and path.

    .PARAMETER CommandName
    The name of the command to check (e.g., "dotnet", "node", "npm").

    .PARAMETER VersionArgument
    The argument to pass to get the version (default: "--version").

    .RETURNS
    A hashtable with status, version, and path information.
    #>
    param(
        [string]$CommandName,
        [string]$VersionArgument = "--version"
    )

    $result = @{
        status = "not_installed"
        version = $null
        path = $null
    }

    try {
        $command = Get-Command $CommandName -ErrorAction SilentlyContinue
        if ($command) {
            $versionOutput = & $CommandName $VersionArgument 2>$null
            if ($versionOutput) {
                $result.version = $versionOutput.ToString().Trim()
                $result.path = $command.Source
                $result.status = "installed"
            }
        }
    }
    catch {
        # Command not found, return default status
    }

    return $result
}

function Test-DependencyVersion {
    <#
    .SYNOPSIS
    Tests if a version meets minimum requirements.

    .PARAMETER CurrentVersion
    The current version string (e.g., "10.0.0", "v18.0.0").

    .PARAMETER MinVersion
    The minimum required version string.

    .PARAMETER MaxVersion
    The maximum allowed version string (optional).

    .RETURNS
    A hashtable with isValid (boolean) and error (string) if invalid.
    #>
    param(
        [string]$CurrentVersion,
        [string]$MinVersion,
        [string]$MaxVersion = $null
    )

    $result = @{
        isValid = $false
        error = $null
    }

    if ([string]::IsNullOrEmpty($CurrentVersion)) {
        $result.error = "Version is empty or null"
        return $result
    }

    # Remove 'v' prefix if present
    $currentVersion = $CurrentVersion -replace '^v', ''
    $minVersion = $MinVersion -replace '^v', ''

    try {
        $current = [version]$currentVersion
        $min = [version]$minVersion

        if ($current -lt $min) {
            $result.error = "Version $CurrentVersion is too low (min: $MinVersion)"
            return $result
        }

        if ($MaxVersion) {
            $maxVersion = $MaxVersion -replace '^v', ''
            $max = [version]$maxVersion
            if ($current -ge $max) {
                $result.error = "Version $CurrentVersion is too high (max: $MaxVersion)"
                return $result
            }
        }

        $result.isValid = $true
    }
    catch {
        $result.error = "Invalid version format: $($_.Exception.Message)"
    }

    return $result
}

function Format-JsonOutput {
    <#
    .SYNOPSIS
    Formats an object as JSON and writes it to a file.

    .PARAMETER Data
    The object to convert to JSON.

    .PARAMETER OutputPath
    The path where the JSON file should be written.

    .PARAMETER Depth
    The depth for JSON serialization (default: 10).
    #>
    param(
        [object]$Data,
        [string]$OutputPath,
        [int]$Depth = 10
    )

    try {
        $json = $Data | ConvertTo-Json -Depth $Depth -Compress:$false
        $json | Out-File -FilePath $OutputPath -Encoding UTF8 -Force
        return $true
    }
    catch {
        Write-Error "Failed to write JSON to $OutputPath : $($_.Exception.Message)"
        return $false
    }
}

function Write-ColorOutput {
    <#
    .SYNOPSIS
    Writes colored output to the console based on status.

    .PARAMETER Message
    The message to write.

    .PARAMETER Status
    The status type: "ok", "error", "warning", or "info".
    #>
    param(
        [string]$Message,
        [string]$Status = "info"
    )

    switch ($Status) {
        "ok" {
            Write-Host "[OK] $Message" -ForegroundColor Green
        }
        "error" {
            Write-Host "[ERROR] $Message" -ForegroundColor Red
        }
        "warning" {
            Write-Host "[WARNING] $Message" -ForegroundColor Yellow
        }
        "info" {
            Write-Host "[INFO] $Message" -ForegroundColor Cyan
        }
        default {
            Write-Host $Message
        }
    }
}

function Get-ScriptDirectory {
    <#
    .SYNOPSIS
    Gets the directory where the script is located.

    .RETURNS
    The full path to the script directory.
    #>
    if ($psise) {
        # Running in PowerShell ISE
        return Split-Path $psise.CurrentFile.FullPath
    }
    elseif ($PSScriptRoot) {
        # Normal PowerShell execution
        return $PSScriptRoot
    }
    else {
        # Fallback to current directory
        return Get-Location
    }
}

function Import-DependenciesEnv {
    <#
    .SYNOPSIS
    Imports the dependencies.env file and returns a hashtable of values.

    .PARAMETER EnvFilePath
    The path to the dependencies.env file.

    .RETURNS
    A hashtable with environment variable values, or null if file not found.
    #>
    param(
        [string]$EnvFilePath
    )

    if (-not (Test-Path $EnvFilePath)) {
        return $null
    }

    $envVars = @{}

    Get-Content $EnvFilePath | ForEach-Object {
        if ($_ -match '^([^=]+)=(.*)$') {
            $name = $matches[1].Trim()
            $value = $matches[2].Trim()
            $envVars[$name] = $value
        }
    }

    return $envVars
}

function New-Timestamp {
    <#
    .SYNOPSIS
    Generates an ISO 8601 timestamp for the current time.

    .RETURNS
    A string representing the current time in ISO 8601 format.
    #>
    return (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
}

# Export functions
Export-ModuleMember -Function @(
    'Get-DependencyStatus',
    'Test-DependencyVersion',
    'Format-JsonOutput',
    'Write-ColorOutput',
    'Get-ScriptDirectory',
    'Import-DependenciesEnv',
    'New-Timestamp'
)
