name: Release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:

# From: https://github.com/rust-lang/rust-analyzer/blob/master/.github/workflows/release.yaml#L13-L21
env:
  CARGO_INCREMENTAL: 0
  CARGO_NET_RETRY: 10
  RUSTUP_MAX_RETRIES: 10

jobs:
  # Server builds for self-hosting
  server-build:
    strategy:
      matrix:
        settings:
          - host: blacksmith-4vcpu-ubuntu-2204
            target: x86_64-unknown-linux-gnu
            platform: linux-x86_64
          - host: blacksmith-4vcpu-ubuntu-2204-arm
            target: aarch64-unknown-linux-gnu
            platform: linux-aarch64
    name: Server - ${{ matrix.settings.platform }}
    runs-on: ${{ matrix.settings.host }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Rust
        uses: ./.github/actions/setup-rust
        with:
          target: ${{ matrix.settings.target }}

      - name: Install VA-API libraries
        if: matrix.settings.target == 'aarch64-unknown-linux-gnu'
        run: sudo apt-get update && sudo apt-get install -y libva-dev libva-drm2

      - name: Setup native dependencies
        run: cargo run -p xtask -- setup
        env:
          TARGET_TRIPLE: ${{ matrix.settings.target }}

      - name: Build server binary
        run: |
          cargo build --release --bin sd-server --features sd-core/heif,sd-core/ffmpeg,sd-core/ai --target ${{ matrix.settings.target }}
        env:
          CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc

      - name: Prepare server binary
        run: |
          mkdir -p dist
          cp target/${{ matrix.settings.target }}/release/sd-server dist/sd-server-${{ matrix.settings.platform }}
          chmod +x dist/sd-server-${{ matrix.settings.platform }}

      - name: Generate checksum
        run: |
          cd dist
          sha256sum sd-server-${{ matrix.settings.platform }} > sd-server-${{ matrix.settings.platform }}.sha256

      - name: Create archive
        run: |
          cd dist
          tar -czf sd-server-${{ matrix.settings.platform }}.tar.gz sd-server-${{ matrix.settings.platform }} sd-server-${{ matrix.settings.platform }}.sha256

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: server-${{ matrix.settings.platform }}
          path: dist/sd-server-${{ matrix.settings.platform }}.tar.gz

  # V2 Desktop builds
  desktop-main:
    strategy:
      fail-fast: false
      matrix:
        settings:
          # macOS builds
          - host: self-hosted
            target: aarch64-apple-darwin
            bundles: dmg,app
            os: darwin
            arch: aarch64
          - host: self-hosted
            target: x86_64-apple-darwin
            bundles: dmg,app
            os: darwin
            arch: x86_64
          # Windows builds
          - host: blacksmith-4vcpu-windows-2025
            target: x86_64-pc-windows-msvc
            bundles: nsis
            os: windows
            arch: x86_64
          # Linux builds
          - host: blacksmith-16vcpu-ubuntu-2404
            target: x86_64-unknown-linux-gnu
            bundles: deb
            os: linux
            arch: x86_64
          - host: blacksmith-8vcpu-ubuntu-2404-arm
            target: aarch64-unknown-linux-gnu
            bundles: deb
            os: linux
            arch: aarch64
    name: Desktop - Main ${{ matrix.settings.target }}
    runs-on: ${{ matrix.settings.host }}
    steps:
      - name: Maximize build space
        if: ${{ runner.os == 'Linux' && matrix.settings.arch != 'aarch64' }}
        uses: easimon/maximize-build-space@master
        with:
          swap-size-mb: 3072
          root-reserve-mb: 6144
          remove-dotnet: 'true'
          remove-codeql: 'true'
          remove-haskell: 'true'
          remove-docker-images: 'true'

      - name: Symlink target to C:\
        if: ${{ runner.os == 'Windows' }}
        shell: powershell
        run: |
          New-Item -ItemType Directory -Force -Path C:\spacedrive_target
          New-Item -Path target -ItemType Junction -Value C:\spacedrive_target

      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install VA-API libraries
        if: matrix.settings.target == 'aarch64-unknown-linux-gnu'
        run: sudo apt-get update && sudo apt-get install -y libva-dev libva-drm2

      - name: Install NASM
        if: ${{ runner.os == 'Windows' }}
        uses: ilammy/setup-nasm@v1

      - name: Install Apple API key
        if: ${{ runner.os == 'macOS' }}
        run: |
          mkdir -p ~/.appstoreconnect/private_keys/
          cd ~/.appstoreconnect/private_keys/
          echo ${{ secrets.APPLE_API_KEY_BASE64 }} >> AuthKey_${{ secrets.APPLE_API_KEY }}.p8.base64
          base64 --decode -i AuthKey_${{ secrets.APPLE_API_KEY }}.p8.base64 -o AuthKey_${{ secrets.APPLE_API_KEY }}.p8
          rm AuthKey_${{ secrets.APPLE_API_KEY }}.p8.base64

      - name: Install Codesigning Certificate
        if: ${{ runner.os == 'macOS' }}
        uses: apple-actions/import-codesign-certs@v2
        with:
          p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
          p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}

      - name: Setup System and Rust
        uses: ./.github/actions/setup-system
        env:
          APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          target: ${{ matrix.settings.target }}

      - name: Setup Bun and dependencies
        uses: ./.github/actions/setup-bun
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Verify native deps were downloaded
        if: runner.os == 'Linux'
        run: |
          echo "=== Native dependencies verification ==="
          if [ ! -d "apps/.deps/lib" ]; then
            echo "ERROR: apps/.deps/lib directory does not exist"
            exit 1
          fi

          echo "Contents of apps/.deps/lib/:"
          ls -lh apps/.deps/lib/ | head -20

          SO_COUNT=$(find apps/.deps/lib/ -name "*.so*" | wc -l)
          echo "Found $SO_COUNT .so files"

          if [ "$SO_COUNT" -eq 0 ]; then
            echo "ERROR: No .so files found in apps/.deps/lib/"
            exit 1
          fi

          echo "✓ Native dependencies verified"

      - name: Set ARM crypto flags
        if: ${{ matrix.settings.arch == 'aarch64' }}
        shell: bash
        run: |
          echo "CFLAGS=-march=armv8.2-a+crypto" >> $GITHUB_ENV
          echo "CXXFLAGS=-march=armv8.2-a+crypto" >> $GITHUB_ENV

      - name: Build with tauri-action
        uses: tauri-apps/tauri-action@v0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
          ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
          APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
          APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
          APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
          APPLE_PROVIDER_SHORT_NAME: ${{ secrets.APPLE_PROVIDER_SHORT_NAME }}
          APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
          APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          CPATH: ${{ github.workspace }}/apps/.deps/include
          C_INCLUDE_PATH: ${{ github.workspace }}/apps/.deps/include
        with:
          projectPath: apps/tauri
          args: >-
            --target ${{ matrix.settings.target }}
            --bundles ${{ matrix.settings.bundles }}
            ${{ matrix.settings.os == 'windows' && '--config src-tauri/tauri.windows.conf.json' || '' }}
          includeUpdaterJson: true

      - name: Package frontend
        if: ${{ runner.os == 'Linux' }}
        run: |
          set -eux
          XZ_OPT='-T0 -7' tar -cJf apps/tauri/dist.tar.xz -C apps/tauri/dist .

      - name: Publish Artifacts
        uses: ./.github/actions/publish-artifacts
        with:
          os: ${{ matrix.settings.os }}
          arch: ${{ matrix.settings.arch }}
          target: ${{ matrix.settings.target }}
          profile: release

      - name: Cleanup keychain
        if: always() && runner.os == 'macOS'
        run: security delete-keychain signing_temp.keychain || true

  # Create unified release with Server, CLI, and Desktop artifacts
  release:
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: blacksmith-4vcpu-ubuntu-2404
    name: Create Release
    needs: [server-build, desktop-main]
    permissions:
      contents: write
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v4

      - name: Create Release
        uses: softprops/action-gh-release@v2
        with:
          draft: true
          files: |
            cli-*/*
            server-*/*
            */*.dmg
            */*.exe
            */*.nsis.zip
            */*.deb
            */*.tar.xz
            */*.tar.gz
            */*.sig
            */*.json
