name: build

on:
  push:
    branches: [pro-features]
  workflow_dispatch:
    inputs:
      version_suffix:
        description: "Version suffix (e.g. 'cst', 'beta1'). Empty = vanilla."
        type: string
        default: "cst"

env:
  # Cargo.lock is lockfile v4, which requires Rust >= 1.78. Upstream's
  # .github/workflows/build.yaml pins 1.90; mirror that here.
  RUST_VERSION: "1.90"
  VERSION_BASE: "1.1.15"
  VERSION_SUFFIX: ${{ inputs.version_suffix || 'cst' }}

jobs:
  build-amd64:
    name: build-linux-amd64
    # Same self-hosted runner as the rustdesk client build. provision.sh on the
    # host installs the Rust toolchain and devscripts/debhelper used here.
    runs-on: [self-hosted, Linux, X64, ubuntu-22.04]
    timeout-minutes: 120
    steps:
      - name: Checkout source
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Verify host toolchain
        shell: bash
        run: |
          required=(git bash rustc cargo rustup pkg-config debuild dh dpkg-deb)
          missing=()
          for t in "${required[@]}"; do
            if command -v "$t" >/dev/null 2>&1; then
              printf '%-20s %s\n' "$t" "$(command -v "$t")"
            else
              missing+=("$t")
              printf '%-20s MISSING\n' "$t"
            fi
          done
          if [[ ${#missing[@]} -gt 0 ]]; then
            echo "Missing tools: ${missing[*]}. Install via: sudo apt install -y devscripts build-essential debhelper pkg-config"
            exit 1
          fi

      - name: Compute version strings
        shell: bash
        run: |
          base="${VERSION_BASE}"
          suffix="${VERSION_SUFFIX}"
          [[ "$base" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
            echo "VERSION_BASE '$base' must be major.minor.patch"; exit 1; }
          if [[ -n "$suffix" ]]; then display="${base}-${suffix}"; else display="${base}"; fi
          echo "Base    : $base"
          echo "Suffix  : $suffix"
          echo "Display : $display"
          echo "VERSION_DISPLAY=$display" >> "$GITHUB_ENV"

      - name: Patch Cargo.toml with display version
        shell: bash
        run: |
          sed -i -E "0,/^version[[:space:]]*=/{s/^version[[:space:]]*=[[:space:]]*\"${VERSION_BASE}\"/version = \"${VERSION_DISPLAY}\"/}" Cargo.toml
          grep '^version' Cargo.toml | head -1

      - name: Patch debian/changelog with display version
        shell: bash
        run: |
          # The .deb filename is derived from the first changelog entry's
          # parenthesized version, NOT from Cargo.toml. Rewrite the leading
          # entry so the produced .debs carry $VERSION_DISPLAY.
          sed -i -E "0,/^rustdesk-server \(${VERSION_BASE}\)/{s/^rustdesk-server \(${VERSION_BASE}\)/rustdesk-server (${VERSION_DISPLAY})/}" debian/changelog
          head -1 debian/changelog

      - name: Ensure Rust toolchain configured
        shell: bash
        run: |
          rustup toolchain install "$RUST_VERSION" --profile minimal --component rustfmt
          rustup default "$RUST_VERSION"
          rustup target add x86_64-unknown-linux-gnu
          rustc --version
          cargo --version

      - name: Build hbbs / hbbr / rustdesk-utils
        shell: bash
        run: |
          set -e
          # Native build for the runner's amd64 host. --all-features matches
          # what upstream's GitHub workflow uses for its musl cross builds.
          cargo build --release --all-features
          mkdir -p debian-build/amd64/bin
          cp -v target/release/hbbs           debian-build/amd64/bin/
          cp -v target/release/hbbr           debian-build/amd64/bin/
          cp -v target/release/rustdesk-utils debian-build/amd64/bin/
          chmod -v a+x debian-build/amd64/bin/*

      - name: Build .deb packages (amd64)
        shell: bash
        run: |
          set -e
          # Mirrors the deb-package job in upstream's .github/workflows/build.yaml:
          # stage debian/ and systemd/ next to the pre-built bin/ tree, then run
          # debuild -b so dh's auto_build step is a no-op (no source detected)
          # and dh_install just packages the binaries listed in the .install files.
          cp -vr debian systemd debian-build/amd64/
          sed "s/{{ ARCH }}/amd64/" debian/control.tpl > debian-build/amd64/debian/control
          (cd debian-build/amd64 && debuild -i -us -uc -b -aamd64)

          mkdir -p ./SignOutput
          mv -v ./debian-build/rustdesk-server-hbbs_${VERSION_DISPLAY}_amd64.deb   ./SignOutput/
          mv -v ./debian-build/rustdesk-server-hbbr_${VERSION_DISPLAY}_amd64.deb   ./SignOutput/
          mv -v ./debian-build/rustdesk-server-utils_${VERSION_DISPLAY}_amd64.deb  ./SignOutput/

      - name: Report signing status of build artifacts
        shell: bash
        run: |
          # .deb files are typically signed with debsign or via the apt repo
          # signing pipeline, not the .deb itself. Just list contents for now.
          for f in ./SignOutput/*.deb; do
            [[ -f "$f" ]] || continue
            size=$(stat -c%s "$f")
            printf '[UNSIGNED] %s (%d bytes)\n' "$(basename "$f")" "$size"
          done
          echo "::warning title=Unsigned .deb::Wire up debsigs / repo signing before distributing."

      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: rustdesk-server-linux-amd64-${{ github.sha }}
          path: SignOutput/rustdesk-server-*.deb
          if-no-files-found: error
          retention-days: 14
