name: Build artifacts (manual)

on:
  workflow_dispatch:
    inputs:
      build_group:
        description: which artifacts to build
        required: true
        default: linux
        type: choice
        options:
          - linux
          - macos
          - windows
          - all
      libghostty_optimize:
        description: libghostty-vt optimize mode for this build
        required: true
        default: ReleaseSafe
        type: choice
        options:
          - ReleaseSafe
          - ReleaseFast
          - ReleaseSmall
          - Debug
      libghostty_simd:
        description: build libghostty-vt with SIMD-accelerated code paths
        required: true
        default: 'false'
        type: choice
        options:
          - 'false'
          - 'true'

permissions:
  contents: read
  actions: write

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
  RUST_TOOLCHAIN_VERSION: 1.96.1

jobs:
  build-linux:
    if: ${{ inputs.build_group == 'linux' || inputs.build_group == 'all' }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            name: herdr-linux-x86_64
          - target: aarch64-unknown-linux-musl
            os: ubuntu-latest
            name: herdr-linux-aarch64
    env:
      LIBGHOSTTY_VT_OPTIMIZE: ${{ inputs.libghostty_optimize }}
      LIBGHOSTTY_VT_SIMD: ${{ inputs.libghostty_simd }}

    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
        with:
          persist-credentials: false

      - name: Install Rust
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1
        with:
          toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }}
          targets: ${{ matrix.target }}

      - name: Install Zig
        uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
        with:
          version: 0.15.2

      - name: Prefer official Ubuntu mirrors over Azure
        run: |
          if [ -f /etc/apt/apt-mirrors.txt ]; then
            sudo sed -i '/azure.archive.ubuntu.com/d' /etc/apt/apt-mirrors.txt
            echo "Using apt mirrors:"
            cat /etc/apt/apt-mirrors.txt
          fi

      - name: Install Linux build tools
        run: |
          sudo find /etc/apt/sources.list.d -type f \( -iname '*microsoft*' -o -iname '*azure-cli*' \) -print -delete
          sudo apt-get update
          sudo apt-get install -y cmake ninja-build musl-tools gcc-aarch64-linux-gnu crossbuild-essential-arm64

      - name: Set Linux aarch64 linker
        if: matrix.target == 'aarch64-unknown-linux-musl'
        run: echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

      - name: Remove Zig caches
        run: rm -rf .zig-cache vendor/libghostty-vt/.zig-cache vendor/libghostty-vt/zig-out

      - name: Build
        run: cargo build --release --locked --target ${{ matrix.target }}

      - name: Package artifact
        run: |
          cp target/${{ matrix.target }}/release/herdr ${{ matrix.name }}
          file ${{ matrix.name }} > BUILD_INFO.txt
          ldd ${{ matrix.name }} 2>&1 | tee -a BUILD_INFO.txt
          grep -q "statically linked" BUILD_INFO.txt
          if nm -u ${{ matrix.name }} 2>/dev/null | grep -E '(__cxa|GLIBCXX|CXXABI|_ZSt)'; then
            echo "error: Linux artifact has unresolved C++ runtime symbols" >&2
            exit 1
          fi
          {
            echo "commit=$GITHUB_SHA"
            echo "target=${{ matrix.target }}"
            echo "libghostty_vt_optimize=$LIBGHOSTTY_VT_OPTIMIZE"
            echo "libghostty_vt_simd=$LIBGHOSTTY_VT_SIMD"
          } >> BUILD_INFO.txt
          python3 -c "import hashlib, pathlib; artifact = pathlib.Path('${{ matrix.name }}'); print(f'sha256={hashlib.sha256(artifact.read_bytes()).hexdigest()}  {artifact.name}')" >> BUILD_INFO.txt

      - name: Upload artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
        with:
          name: ${{ matrix.name }}-${{ inputs.libghostty_optimize }}-simd-${{ inputs.libghostty_simd }}
          path: |
            ${{ matrix.name }}
            BUILD_INFO.txt
          retention-days: 7

  build-macos:
    if: ${{ inputs.build_group == 'macos' || inputs.build_group == 'all' }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-apple-darwin
            os: macos-latest
            name: herdr-macos-x86_64
          - target: aarch64-apple-darwin
            os: macos-latest
            name: herdr-macos-aarch64
    env:
      LIBGHOSTTY_VT_OPTIMIZE: ${{ inputs.libghostty_optimize }}
      LIBGHOSTTY_VT_SIMD: ${{ inputs.libghostty_simd }}

    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
        with:
          persist-credentials: false

      - name: Install Rust
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1
        with:
          toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }}
          targets: ${{ matrix.target }}

      - name: Install Zig
        uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
        with:
          version: 0.15.2

      - name: Install macOS build tools
        run: brew install cmake ninja

      - name: Remove Zig caches
        run: rm -rf .zig-cache vendor/libghostty-vt/.zig-cache vendor/libghostty-vt/zig-out

      - name: Build
        run: cargo build --release --locked --target ${{ matrix.target }}

      - name: Package artifact
        run: |
          cp target/${{ matrix.target }}/release/herdr ${{ matrix.name }}
          file ${{ matrix.name }} > BUILD_INFO.txt
          {
            echo "commit=$GITHUB_SHA"
            echo "target=${{ matrix.target }}"
            echo "libghostty_vt_optimize=$LIBGHOSTTY_VT_OPTIMIZE"
            echo "libghostty_vt_simd=$LIBGHOSTTY_VT_SIMD"
          } >> BUILD_INFO.txt
          python3 -c "import hashlib, pathlib; artifact = pathlib.Path('${{ matrix.name }}'); print(f'sha256={hashlib.sha256(artifact.read_bytes()).hexdigest()}  {artifact.name}')" >> BUILD_INFO.txt

      - name: Upload artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
        with:
          name: ${{ matrix.name }}-${{ inputs.libghostty_optimize }}-simd-${{ inputs.libghostty_simd }}
          path: |
            ${{ matrix.name }}
            BUILD_INFO.txt
          retention-days: 7

  build-windows:
    if: ${{ inputs.build_group == 'windows' || inputs.build_group == 'all' }}
    runs-on: windows-latest
    env:
      LIBGHOSTTY_VT_OPTIMIZE: ${{ inputs.libghostty_optimize }}
      LIBGHOSTTY_VT_SIMD: ${{ inputs.libghostty_simd }}

    steps:
      - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
        with:
          persist-credentials: false

      - name: Install Rust
        uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # v1
        with:
          toolchain: ${{ env.RUST_TOOLCHAIN_VERSION }}
          targets: x86_64-pc-windows-msvc

      - name: Install Zig
        uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
        with:
          version: 0.15.2

      - name: Remove Zig caches
        shell: pwsh
        run: |
          Remove-Item -Recurse -Force .zig-cache -ErrorAction SilentlyContinue
          Remove-Item -Recurse -Force vendor/libghostty-vt/.zig-cache -ErrorAction SilentlyContinue
          Remove-Item -Recurse -Force vendor/libghostty-vt/zig-out -ErrorAction SilentlyContinue

      - name: Build
        run: cargo build --release --locked --target x86_64-pc-windows-msvc

      - name: Package artifact
        shell: pwsh
        run: |
          $ErrorActionPreference = "Stop"
          $package = Join-Path $env:RUNNER_TEMP "Microsoft.Windows.Console.ConPTY.nupkg"
          $stage = Join-Path $env:RUNNER_TEMP "herdr-windows-x86_64"
          .\scripts\package_windows_conpty.ps1 `
            -HerdrExe target\x86_64-pc-windows-msvc\release\herdr.exe `
            -PackagePath $package `
            -StageDir $stage `
            -OutputPath herdr-windows-x86_64.zip
          "commit=$env:GITHUB_SHA" | Out-File -Encoding utf8 BUILD_INFO.txt
          "target=x86_64-pc-windows-msvc" | Out-File -Encoding utf8 -Append BUILD_INFO.txt
          "libghostty_vt_optimize=$env:LIBGHOSTTY_VT_OPTIMIZE" | Out-File -Encoding utf8 -Append BUILD_INFO.txt
          "libghostty_vt_simd=$env:LIBGHOSTTY_VT_SIMD" | Out-File -Encoding utf8 -Append BUILD_INFO.txt
          $hash = (Get-FileHash -Algorithm SHA256 herdr-windows-x86_64.zip).Hash.ToLowerInvariant()
          "sha256=$hash  herdr-windows-x86_64.zip" | Out-File -Encoding utf8 -Append BUILD_INFO.txt

      - name: Upload artifact
        uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
        with:
          name: herdr-windows-x86_64-${{ inputs.libghostty_optimize }}-simd-${{ inputs.libghostty_simd }}
          path: |
            herdr-windows-x86_64.zip
            BUILD_INFO.txt
          retention-days: 7
