name: Release

on:
  push:
    tags:
      - 'v[0-9]*'

permissions:
  contents: write

jobs:
  create-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    steps:
      - uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true

  build:
    name: Build ${{ matrix.target }}
    needs: create-release
    runs-on: ${{ matrix.os }}
    container: ${{ matrix.container }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-24.04
            target: x86_64-unknown-linux-gnu
            container: archlinux:latest

          - os: macos-14
            target: aarch64-apple-darwin

          # - os: macos-13
          #   target: x86_64-apple-darwin

          - os: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
            container: fedora:43

          - os: windows-latest
            target: x86_64-pc-windows-gnu

    steps:
      - uses: actions/checkout@v4

      # ── Linux x86_64 (Arch container) ────────────────────────────────────────
      - name: Install system deps (Linux x86_64)
        if: matrix.target == 'x86_64-unknown-linux-gnu'
        run: |
          pacman -Sy --noconfirm \
            base-devel \
            gtk4 \
            libadwaita \
            opus \
            alsa-lib \
            pkgconf \
            curl \
            git

      # ── Linux aarch64 (Fedora container on arm64 runner) ─────────────────────
      - name: Install system deps (Linux aarch64)
        if: matrix.target == 'aarch64-unknown-linux-gnu'
        run: |
          dnf install -y \
            gcc \
            gtk4-devel \
            libadwaita-devel \
            opus-devel \
            alsa-lib-devel \
            sqlite-devel \
            pkgconf-pkg-config \
            git

      # ── macOS ──────────────────────────────────────────────────────────────
      - name: Install system deps (macOS)
        if: runner.os == 'macOS'
        run: brew install gtk4 libadwaita pango opus pkg-config glib

      - name: Export brew env (macOS)
        if: runner.os == 'macOS'
        run: |
          BREW="$(brew --prefix)"
          echo "PKG_CONFIG_PATH=${BREW}/lib/pkgconfig:${BREW}/share/pkgconfig" >> "$GITHUB_ENV"
          echo "LIBRARY_PATH=${BREW}/lib"   >> "$GITHUB_ENV"
          echo "CPATH=${BREW}/include"      >> "$GITHUB_ENV"
          echo "RUSTFLAGS=-L ${BREW}/lib"   >> "$GITHUB_ENV"

      # ── Windows (MSYS2 / MINGW64) ─────────────────────────────────────────
      - name: Install system deps (Windows)
        if: runner.os == 'Windows'
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          update: true
          path-type: inherit
          install: >-
            mingw-w64-x86_64-gtk4
            mingw-w64-x86_64-libadwaita
            mingw-w64-x86_64-opus
            mingw-w64-x86_64-pkg-config
            mingw-w64-x86_64-toolchain
            zip

      - name: Export MSYS2 env (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: |
          echo "PKG_CONFIG_PATH=/mingw64/lib/pkgconfig:/mingw64/share/pkgconfig" >> "$GITHUB_ENV"
          echo "PKG_CONFIG_ALLOW_CROSS=1" >> "$GITHUB_ENV"
          echo "LIBRARY_PATH=/mingw64/lib" >> "$GITHUB_ENV"
          echo "CPATH=/mingw64/include" >> "$GITHUB_ENV"
          echo "RUSTFLAGS=-L /mingw64/lib" >> "$GITHUB_ENV"
      # ── Rust toolchain ────────────────────────────────────────────────────
      - name: Install Rust toolchain
        if: runner.os != 'Windows'
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      # Windows must use the GNU toolchain; stable defaults to MSVC which can't
      # link against MinGW .a files and fails with LNK1181 on gio-2.0.lib.
      - name: Install Rust toolchain (Windows GNU)
        if: runner.os == 'Windows'
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable-x86_64-pc-windows-gnu
          targets: x86_64-pc-windows-gnu

      # ── Cargo registry cache ───────────────────────────────────────────────
      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
          key: ${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-${{ matrix.target }}-cargo-

      # ── Build ──────────────────────────────────────────────────────────────
      - name: Build (non-Windows)
        if: runner.os != 'Windows'
        run: cargo build --release --bin zodia --target ${{ matrix.target }}

      - name: Build (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: cargo build --release --bin zodia --target ${{ matrix.target }}

      # ── Package — Linux ────────────────────────────────────────────────────
      - name: Package (Linux)
        if: runner.os == 'Linux'
        run: |
          BIN=target/${{ matrix.target }}/release/zodia
          strip "$BIN"
          cp "$BIN" zodia-${{ matrix.target }}

      # ── Package — macOS .app bundle ────────────────────────────────────────
      - name: Package (macOS)
        if: runner.os == 'macOS'
        run: |
          APP=Zodia.app
          SVG=app/data/io.github.bendik.Zodia.svg
          mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
          cp target/${{ matrix.target }}/release/zodia "$APP/Contents/MacOS/zodia-bin"

          # ── .icns via ImageMagick + iconutil ──────────────────────────────
          brew install imagemagick dylibbundler
          ICONSET=$(mktemp -d)/Zodia.iconset
          mkdir -p "$ICONSET"
          render() { magick -background none -density 300 "$SVG" -resize "$1x$1" +profile '*' "${ICONSET}/$2"; }
          render 16   icon_16x16.png
          render 32   icon_16x16@2x.png
          render 32   icon_32x32.png
          render 64   icon_32x32@2x.png
          render 128  icon_128x128.png
          render 256  icon_128x128@2x.png
          render 256  icon_256x256.png
          render 512  icon_256x256@2x.png
          render 512  icon_512x512.png
          render 1024 icon_512x512@2x.png
          iconutil -c icns -o "$APP/Contents/Resources/zodia.icns" "$ICONSET"

          # ── Info.plist ────────────────────────────────────────────────────
          cat > "$APP/Contents/Info.plist" <<'PLIST'
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
            "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
          <plist version="1.0">
          <dict>
            <key>CFBundleName</key>               <string>Zodia</string>
            <key>CFBundleDisplayName</key>        <string>Zodia</string>
            <key>CFBundleIdentifier</key>         <string>io.github.bendik.Zodia</string>
            <key>CFBundleVersion</key>            <string>${{ github.ref_name }}</string>
            <key>CFBundleShortVersionString</key> <string>${{ github.ref_name }}</string>
            <key>CFBundlePackageType</key>        <string>APPL</string>
            <key>CFBundleExecutable</key>         <string>zodia</string>
            <key>CFBundleIconFile</key>           <string>zodia</string>
            <key>LSMinimumSystemVersion</key>     <string>13.0</string>
            <key>NSHighResolutionCapable</key>    <true/>
            <key>NSHumanReadableCopyright</key>   <string>AGPL-3.0-or-later</string>
          </dict>
          </plist>
          PLIST

          # ── dylibbundler ──────────────────────────────────────────────────
          BREW="$(brew --prefix)"
          dylibbundler \
            --bundle-deps \
            --fix-file "$APP/Contents/MacOS/zodia-bin" \
            --dest-dir "$APP/Contents/libs" \
            --install-path "@executable_path/../libs" \
            --search-path "${BREW}/lib" \
            --overwrite-dir

          # ── Launcher: sets XDG_DATA_DIRS then execs the real binary ───────
          cat > "$APP/Contents/MacOS/zodia" <<SH
          #!/bin/sh
          BUNDLE="\$(cd "\$(dirname "\$0")/../.." && pwd)"
          export XDG_DATA_DIRS="\$BUNDLE/Contents/Resources/share:${BREW}/share"
          export GDK_PIXBUF_MODULE_FILE="${BREW}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
          exec "\$BUNDLE/Contents/MacOS/zodia-bin" "\$@"
          SH
          chmod +x "$APP/Contents/MacOS/zodia"

          zip -r "zodia-${{ matrix.target }}.zip" "$APP"

      # ── Package — Windows DLL bundle ───────────────────────────────────────
      - name: Package (Windows)
        if: runner.os == 'Windows'
        shell: msys2 {0}
        run: |
          DIST=zodia-windows
          mkdir -p "$DIST/share/glib-2.0"
          cp target/${{ matrix.target }}/release/zodia.exe "$DIST/"

          # Copy every mingw64 DLL the binary transitively depends on
          ldd target/${{ matrix.target }}/release/zodia.exe \
            | grep '/mingw64/' \
            | awk '{print $3}' \
            | xargs -I{} cp -n {} "$DIST/"

          # GLib compiled schemas
          [ -d "/mingw64/share/glib-2.0/schemas" ] && \
            cp -r /mingw64/share/glib-2.0/schemas "$DIST/share/glib-2.0/"

          # GTK4 default settings / CSS
          [ -d "/mingw64/share/gtk-4.0" ] && \
            cp -r /mingw64/share/gtk-4.0 "$DIST/share/"

          # Helper executables GTK spawns at runtime
          for bin in gdbus gspawn-win64-helper gspawn-win64-helper-console; do
            [ -f "/mingw64/bin/${bin}.exe" ] && cp "/mingw64/bin/${bin}.exe" "$DIST/"
          done

          # Launcher .cmd: sets XDG_DATA_DIRS to the bundle's share/ directory
          cat > "$DIST/Zodia.cmd" <<'CMD'
          @echo off
          set "HERE=%~dp0"
          set "XDG_DATA_DIRS=%HERE%share"
          start /B "" "%HERE%zodia.exe" %*
          CMD

          zip -r "zodia-${{ matrix.target }}.zip" "$DIST"

      # ── Upload to GitHub Release ───────────────────────────────────────────
      - name: Upload Linux artifact
        if: runner.os == 'Linux'
        uses: softprops/action-gh-release@v2
        with:
          files: zodia-${{ matrix.target }}

      - name: Upload macOS artifact
        if: runner.os == 'macOS'
        uses: softprops/action-gh-release@v2
        with:
          files: zodia-${{ matrix.target }}.zip

      - name: Upload Windows artifact
        if: runner.os == 'Windows'
        uses: softprops/action-gh-release@v2
        with:
          files: zodia-${{ matrix.target }}.zip

