src/Interact/main.ps1

param ($Locale)

#_if PSScript
# 加载本地化数据
. "$PSScriptRoot\..\predicate.ps1"
. "$PSScriptRoot\..\TaskbarProgress.ps1"
. "$PSScriptRoot\..\WriteI18n.ps1"
$LocalizeData = . "$PSScriptRoot\..\LocaleLoader.ps1" -Locale $Locale
Set-I18nData -I18nData $LocalizeData.InteractI18nData
$I18n = $LocalizeData.InteractI18nData

# 为交互模式设置窗口标题
$OldTitle = $Host.UI.RawUI.WindowTitle
$Host.UI.RawUI.WindowTitle = "ps12exe - $($I18n.ModeName)"

try {
    Write-SymboledWelcomeI18n Welcome

    while ($true) {
        $cmdParams = [System.Collections.ArrayList]::new()
        Write-TaskbarProgress -Percent 0

        # 输入文件提示
        $inputFile = ''
        do {
            Write-SymboledInfoI18n EnterInputFile
            Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
            $inputFile = Read-Host
            if (-not $inputFile) {
                Write-SymboledErrorI18n InvalidInputFile
            }
            elseif ($inputFile -match "^(https?|ftp)://") {
                # URL:使用 HEAD 请求验证文件是否存在
                try {
                    $null = Invoke-WebRequest -Uri $inputFile -Method Head -ErrorAction Stop
                    # 对于 URL,扩展名检查是可选的(URL 可能没有扩展名);但如果查询字符串或片段之前有扩展名,则它应当是有效的
                    $urlWithoutQuery = $inputFile -replace '[?#].*$', ''
                    if ($urlWithoutQuery -match "\.(ps1|psd1|tmp)$") {
                        # 有效的 URL 且扩展名有效
                    }
                    elseif ($urlWithoutQuery -match "\.[^./]+$") {
                        # URL 有扩展名但无效
                        Write-SymboledErrorI18n InvalidExtension
                        $inputFile = ''
                    }
                    # 如果没有扩展名,则接受它(URL 没有扩展名也可能可用)
                }
                catch {
                    Write-SymboledErrorI18n FileDoesNotExist
                    $inputFile = ''
                }
            }
            else {
                # 本地文件路径
                if (-not (Test-Path -LiteralPath $inputFile -PathType Leaf)) {
                    Write-SymboledErrorI18n FileDoesNotExist
                    $inputFile = ''
                }
                elseif ($inputFile -notmatch "\.(ps1|psd1|tmp)$") {
                    Write-SymboledErrorI18n InvalidExtension
                    $inputFile = ''
                }
            }
        } while (-not $inputFile)
        $cmdParams.Add("-inputFile `"$inputFile`"") | Out-Null
        Write-TaskbarProgress -Percent 15

        # 输出文件提示
        $outputFile = ''
        Write-SymboledInfoI18n EnterOutputFile
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        $outputFile = Read-Host
        if ($outputFile) {
            if ($outputFile -notmatch "\.(exe|com|scr|bin|bat|cmd)$") {
                Write-SymboledErrorI18n OutputFileExtensionError
                $outputFile += ".exe"
            }
            $cmdParams.Add("-outputFile `"$outputFile`"") | Out-Null
        }
        Write-TaskbarProgress -Percent 30

        # 附加信息提示
        Write-SymboledQuestionI18n AddAdditionalInfo AdditionalInfoPrompt
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        if (IsEnable(Read-Host)) {
            Write-SymboledProgressI18n CollectingInfo
            $resources = @{}

            # 图标
            $icon = ''
            do {
                Write-SymboledInfoI18n IconPath
                Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
                $iconInput = Read-Host
                if ($iconInput) {
                    $isValid = $false
                    if ($iconInput -match "^(https?|ftp)://") {
                        # URL:使用 HEAD 请求验证文件是否存在
                        try {
                            $null = Invoke-WebRequest -Uri $iconInput -Method Head -ErrorAction Stop
                            $isValid = $true
                        }
                        catch {
                            Write-SymboledErrorI18n IconDoesNotExist
                        }
                    }
                    else {
                        # 本地文件路径
                        if (Test-Path -LiteralPath $iconInput -PathType Leaf) {
                            $isValid = $true
                        }
                        else {
                            Write-SymboledErrorI18n IconDoesNotExist
                        }
                    }

                    if ($isValid) {
                        $icon = $iconInput
                        $resources.Icon = $icon
                        break
                    }
                }
                else {
                    # 用户留空以跳过图标
                    break
                }
            } while ($true)

            # 其他资源
            $resourcePrompts = @{
                Title       = $I18n.EnterTitle
                Description = $I18n.EnterDescription
                Company     = $I18n.EnterCompany
                Product     = $I18n.EnterProduct
                Copyright   = $I18n.EnterCopyright
                Trademark   = $I18n.EnterTrademark
            }
            foreach ($key in $resourcePrompts.Keys) {
                Write-SymboledInfoI18n EnterResourcePrompt -MessageFormatArgs $resourcePrompts[$key]
                Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
                $value = Read-Host
                if ($value) { $resources[$key] = $value }
            }

            # 版本
            Write-SymboledInfoI18n Version
            Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
            $version = Read-Host
            if ($version) {
                if ($version -notmatch '^\d+(\.\d+){0,3}$') {
                    Write-SymboledInvalidI18n InvalidVersionFormat
                }
                else {
                    $resources.Version = $version
                }
            }

            if ($resources.Count -gt 0) {
                $resourcesStr = $resources.GetEnumerator() | ForEach-Object { "$($_.Key)='$($_.Value -replace "'", "''")'" } | Join-String -Separator '; '
                $cmdParams.Add("-Resources @{$resourcesStr}") | Out-Null
            }
        }
        else {
            Write-SymboledProgressI18n SkippingAdditionalInfo
        }
        Write-TaskbarProgress -Percent 50

        # 其他选项
        Write-SymboledQuestionI18n CompileAsGui AdditionalInfoPrompt
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        if (IsEnable(Read-Host)) {
            $cmdParams.Add("-App @{Windowed=`$true}") | Out-Null
        }
        Write-TaskbarProgress -Percent 60

        Write-SymboledQuestionI18n RequireAdmin AdditionalInfoPrompt
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        if (IsEnable(Read-Host)) {
            $cmdParams.Add("-Os @{Admin=`$true}") | Out-Null
        }
        Write-TaskbarProgress -Percent 70

        # 代码签名
        Write-SymboledQuestionI18n EnableCodeSigning AdditionalInfoPrompt
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        if (IsEnable(Read-Host)) {
            $codeSigningParams = @{}

            # 证书路径
            $certPath = ''
            do {
                Write-SymboledInfoI18n EnterCertificatePath
                Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
                $certPathInput = Read-Host
                if ($certPathInput) {
                    $isValid = $false
                    if ($certPathInput -notmatch '\.pfx$') {
                        Write-SymboledErrorI18n InvalidCertificateExtension
                    }
                    elseif ($certPathInput -match "^(https?|ftp)://") {
                        # URL:使用 HEAD 请求验证文件是否存在
                        try {
                            $null = Invoke-WebRequest -Uri $certPathInput -Method Head -ErrorAction Stop
                            $isValid = $true
                        }
                        catch {
                            Write-SymboledErrorI18n CertificateDoesNotExist
                        }
                    }
                    else {
                        # 本地文件路径
                        if (Test-Path -LiteralPath $certPathInput -PathType Leaf) {
                            $isValid = $true
                        }
                        else {
                            Write-SymboledErrorI18n CertificateDoesNotExist
                        }
                    }

                    if ($isValid) {
                        $certPath = $certPathInput
                        $codeSigningParams.Certificate = $certPath

                        # 证书密码
                        Write-SymboledInfoI18n EnterCertificatePassword
                        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
                        $certPassword = Read-Host -AsSecureString
                        if ($certPassword) {
                            $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($certPassword)
                            $codeSigningParams.Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
                            [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
                        }
                        break
                    }
                }
                else {
                    # 用户留空以跳过证书路径
                    break
                }
            } while ($true)

            # 证书指纹
            Write-SymboledInfoI18n EnterCertificateThumbprint
            Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
            $thumbprint = Read-Host
            if ($thumbprint) {
                $codeSigningParams.Thumbprint = $thumbprint
            }

            # 时间戳服务器
            Write-SymboledInfoI18n EnterTimestampServer
            Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
            $timestampServer = Read-Host
            if ($timestampServer) {
                $codeSigningParams.Timestamp = $timestampServer
            }
            else {
                # 使用默认时间戳服务器
                $codeSigningParams.Timestamp = "http://timestamp.digicert.com"
            }

            if ($codeSigningParams.Count -gt 0) {
                $codeSigningParamsStr = $codeSigningParams.GetEnumerator() | ForEach-Object {
                    if ($_.Key -eq 'Password') {
                        "$($_.Key)='$($_.Value -replace "'", "''")'"
                    }
                    else {
                        "$($_.Key)='$($_.Value -replace "'", "''")'"
                    }
                } | Join-String -Separator '; '
                $cmdParams.Add("-Signing @{$codeSigningParamsStr}") | Out-Null
            }
        }
        else {
            Write-SymboledProgressI18n SkippingCodeSigning
        }
        Write-TaskbarProgress -Percent 85

        # 构建并执行命令
        Write-SymboledProgressI18n BuildingCommand
        if (Get-Command ps12exe -ErrorAction SilentlyContinue) {
            $command = "ps12exe " + ($cmdParams -join ' ')
        }
        else {
            $scriptPath = Join-Path $PSScriptRoot '..\..\ps12exe.ps1'
            $command = "& `"$scriptPath`" " + ($cmdParams -join ' ')
        }

        Write-SymboledProgressI18n ExecutingCommand
        Write-Host $command
        Write-TaskbarProgress -Percent 90

        try {
            Write-TaskbarProgress
            Invoke-Expression $command
            if ($LASTEXITCODE -eq 0) {
                Write-TaskbarProgressClear
                Write-SymboledSuccessI18n CompileSuccess
            }
            else {
                Write-TaskbarProgressError
                Write-SymboledErrorI18n CompileFailed -MessageFormatArgs $LASTEXITCODE
            }
        }
        catch {
            Write-TaskbarProgressError
            Write-SymboledErrorI18n CompileFailedException -MessageFormatArgs $_.Exception.Message
        }

        Write-SymboledQuestionI18n CompileAnother AdditionalInfoPrompt
        Write-Host -ForegroundColor Gray $I18n.Prompt -NoNewline
        if (-not (IsEnable(Read-Host))) {
            break
        }
    }

    Write-SymboledExitI18n ExitMessage
}
finally {
    Write-TaskbarProgressClear
    $Host.UI.RawUI.WindowTitle = $OldTitle
}
#_else
#_require ps12exe
#_pragma Resources.iconFile $PSScriptRoot/../../img/icon.ico
#_pragma Resources.title ps12exe - Interact
#_pragma Resources.description 'A super cool tool for compile powershell scripts'
#_!!Enter-ps12exeInteract @PSBoundParameters
#_endif