name: Publish INI and Offset Finder Tools

on:
  push:
    branches: [main, master]
    paths:
      - 'res/rdpwrap.ini'
      - 'tools/RDPWrapOffsetFinder/**'
      - '.github/workflows/publish-ini.yml'
  workflow_dispatch:

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

permissions:
  contents: write

jobs:
  publish:
    runs-on: windows-2022

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      # ── Build rdpwrap.dll for both x64 and Win32 ────────────────────────────
      - name: Setup MSBuild
        uses: microsoft/setup-msbuild@v3

      - name: Build rdpwrap.dll (x64 and Win32)
        shell: pwsh
        run: |
          foreach ($platform in @('x64', 'Win32')) {
            msbuild src-x86-x64-Fusix/RDPWrap.vcxproj `
              /p:Configuration=Release `
              /p:Platform="$platform" `
              /p:PlatformToolset=v143 `
              /p:WindowsTargetPlatformVersion=10.0 `
              /v:minimal
          }
          Copy-Item src-x86-x64-Fusix/x64/Release/rdpwrap.dll   .\rdpwrap_x64.dll
          Copy-Item src-x86-x64-Fusix/Win32/Release/rdpwrap.dll .\rdpwrap_x86.dll
          Write-Host "Built DLLs:"
          Get-Item .\rdpwrap_x64.dll, .\rdpwrap_x86.dll | Format-Table Name, Length

      # ── Extract the date string used for tagging and the updated field ──────
      - name: Get release metadata
        id: meta
        shell: pwsh
        run: |
          $date  = Get-Date -Format "yyyy.MM.dd.HHmm"
          $stamp = Get-Date -Format "yyyy-MM-dd HH:mm UTC"

          # Pull the Updated= line out of the INI to surface in release notes
          $iniContent = Get-Content res/rdpwrap.ini -Raw
          $iniDate    = if ($iniContent -match 'Updated=([^\r\n]+)') { $Matches[1] } else { 'unknown' }

          echo "date=$date"       >> $env:GITHUB_OUTPUT
          echo "stamp=$stamp"     >> $env:GITHUB_OUTPUT
          echo "inidate=$iniDate" >> $env:GITHUB_OUTPUT

      # ── Stage RDPWrapOffsetFinder from committed tools/ ──────────────────────
      - name: Stage RDPWrapOffsetFinder from tools/
        id: finder
        shell: pwsh
        run: |
          $version = (Get-Content tools/RDPWrapOffsetFinder/VERSION -Raw).Trim()

          Copy-Item tools/RDPWrapOffsetFinder/x64/RDPWrapOffsetFinder.exe .\RDPWrapOffsetFinder_x64.exe
          Copy-Item tools/RDPWrapOffsetFinder/x64/Zydis.dll               .\Zydis_x64.dll
          Copy-Item tools/RDPWrapOffsetFinder/x86/RDPWrapOffsetFinder.exe .\RDPWrapOffsetFinder_x86.exe
          Copy-Item tools/RDPWrapOffsetFinder/x86/Zydis.dll               .\Zydis_x86.dll

          Write-Host "Staged finder tools (version $version):"
          Get-Item .\RDPWrapOffsetFinder_*.exe, .\Zydis_*.dll | Format-Table Name, Length

          echo "finder_ver=$version" >> $env:GITHUB_OUTPUT

      # ── Download the latest rdpWrapper GUI app from sergiye ─────────────────
      - name: Download rdpWrapper (sergiye)
        id: wrapper
        shell: pwsh
        run: |
          $apiUrl  = "https://api.github.com/repos/sergiye/rdpWrapper/releases/latest"
          $release = Invoke-RestMethod -Uri $apiUrl -Headers @{ "User-Agent" = "rdpwrap-ci" }

          foreach ($arch in @('x64', 'x86')) {
            $asset = $release.assets |
              Where-Object { $_.name -eq "rdpWrapper_$arch.exe" } |
              Select-Object -First 1
            if (-not $asset) {
              throw "Could not find rdpWrapper_$arch.exe in sergiye release $($release.tag_name)"
            }
            Write-Host "Downloading $($asset.browser_download_url)"
            Invoke-WebRequest -Uri $asset.browser_download_url -OutFile ".\rdpWrapper_$arch.exe"
          }

          Write-Host "Wrapper exes:"
          Get-Item .\rdpWrapper_x64.exe, .\rdpWrapper_x86.exe | Format-Table Name, Length
          echo "wrapper_ver=$($release.tag_name)" >> $env:GITHUB_OUTPUT

      # ── Validate the INI has required sections ───────────────────────────────
      - name: Validate INI
        shell: pwsh
        run: |
          $ini = Get-Content res/rdpwrap.ini -Raw
          foreach ($section in @('[Main]', '[SLPolicy]', '[PatchCodes]')) {
            if ($ini -notmatch [regex]::Escape($section)) {
              throw "INI validation failed: missing required section $section"
            }
          }
          $sectionCount = ([regex]::Matches($ini, '^\[[\d\.]+\]', 'Multiline')).Count
          Write-Host "INI is valid. Windows-version sections: $sectionCount"

      # ── Assemble the two user-facing distribution bundles ────────────────────
      - name: Create distribution bundles
        shell: pwsh
        run: |
          # RDPWrapper.zip - complete install package
          $d = ".\bundle_wrapper"
          New-Item -ItemType Directory -Path $d -Force | Out-Null
          Copy-Item .\rdpwrap_x64.dll    "$d\rdpwrap_x64.dll"
          Copy-Item .\rdpwrap_x86.dll    "$d\rdpwrap_x86.dll"
          Copy-Item .\rdpWrapper_x64.exe "$d\rdpWrapper_x64.exe"
          Copy-Item .\rdpWrapper_x86.exe "$d\rdpWrapper_x86.exe"
          Copy-Item res\rdpwrap.ini      "$d\rdpwrap.ini"
          Copy-Item bin\install.bat      "$d\install.bat"
          Copy-Item bin\uninstall.bat    "$d\uninstall.bat"
          Copy-Item bin\update.bat       "$d\update.bat"
          Compress-Archive -Path "$d\*" -DestinationPath ".\RDPWrapper.zip" -Force
          Remove-Item $d -Recurse -Force

          # RDPWrapOffsetFinder.zip - offset finder with per-arch subfolders
          $f = ".\bundle_finder"
          foreach ($arch in @('x64', 'x86')) {
            $dir = "$f\$arch"
            New-Item -ItemType Directory -Path $dir -Force | Out-Null
            Copy-Item ".\RDPWrapOffsetFinder_$arch.exe" "$dir\RDPWrapOffsetFinder.exe"
            Copy-Item ".\Zydis_$arch.dll"               "$dir\Zydis.dll"
          }
          Compress-Archive -Path "$f\*" -DestinationPath ".\RDPWrapOffsetFinder.zip" -Force
          Remove-Item $f -Recurse -Force

          Write-Host "Distribution bundles:"
          Get-Item .\RDPWrapper.zip, .\RDPWrapOffsetFinder.zip | Format-Table Name, Length

      # ── Create/update a versioned GitHub Release with all assets ─────────────
      - name: Publish release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: "ini-${{ steps.meta.outputs.date }}"
          name: "INI Update ${{ steps.meta.outputs.date }}"
          prerelease: false
          make_latest: true
          body: |
            ## RDP Wrapper - Automated Release

            | Field | Value |
            |---|---|
            | INI `Updated` date | `${{ steps.meta.outputs.inidate }}` |
            | Published | ${{ steps.meta.outputs.stamp }} |
            | rdpWrapper (sergiye) | ${{ steps.wrapper.outputs.wrapper_ver }} |
            | RDPWrapOffsetFinder (llccd) | ${{ steps.finder.outputs.finder_ver }} |

            ### Downloads

            | File | Contents | Use |
            |---|---|---|
            | `RDPWrapper.zip` | rdpwrap_x64.dll, rdpwrap_x86.dll, rdpWrapper_x64.exe, rdpWrapper_x86.exe, rdpwrap.ini, install/uninstall/update.bat | Main install package - extract and run `rdpWrapper_x64.exe` |
            | `RDPWrapOffsetFinder.zip` | x64\RDPWrapOffsetFinder.exe + Zydis.dll, x86\RDPWrapOffsetFinder.exe + Zydis.dll | Generate offsets for an unknown termsrv.dll version manually |

            ### Individual files (used by the automated installer)

            | File | Purpose |
            |---|---|
            | `rdpwrap.ini` | Offset database fetched automatically by the installer |
            | `RDPWrapOffsetFinder_x64.exe` / `Zydis_x64.dll` | Loose x64 binaries downloaded by `TryAutoGenerateOffsets` |
            | `RDPWrapOffsetFinder_x86.exe` / `Zydis_x86.dll` | Loose x86 binaries downloaded by `TryAutoGenerateOffsets` |
          files: |
            RDPWrapper.zip
            RDPWrapOffsetFinder.zip
            res/rdpwrap.ini
            rdpwrap_x64.dll
            rdpwrap_x86.dll
            RDPWrapOffsetFinder_x64.exe
            RDPWrapOffsetFinder_x86.exe
            Zydis_x64.dll
            Zydis_x86.dll
