name: Build & Release macOS .dmg

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:    # bouton manuel dans l'UI GitHub

permissions:
  contents: write       # nécessaire pour créer/upload les releases

jobs:
  build-mac:
    runs-on: macos-14   # Apple Silicon (arm64)
    timeout-minutes: 60

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Xcode
        uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: latest-stable

      - name: Install build dependencies (libusb + create-dmg)
        run: |
          brew install libusb create-dmg

      - name: Download SuperCollider 3.14
        run: |
          mkdir -p ~/sc-dl
          curl -sL --max-time 300 -o ~/sc-dl/sc.dmg \
            https://github.com/supercollider/supercollider/releases/download/Version-3.14.0/SuperCollider-3.14.0-macOS-universal.dmg
          ls -lh ~/sc-dl/sc.dmg
          hdiutil attach -nobrowse -quiet ~/sc-dl/sc.dmg
          ls /Volumes/ | head -5
          # Le volume s'appelle "SuperCollider 3.14.0" ou similaire
          SC_VOL=$(ls /Volumes | grep -i SuperCollider | head -1)
          mkdir -p ~/sc-extracted
          cp -R "/Volumes/$SC_VOL/SuperCollider.app" ~/sc-extracted/
          hdiutil detach "/Volumes/$SC_VOL" -quiet
          ls -lh ~/sc-extracted/SuperCollider.app/Contents/MacOS/

      - name: Download Node.js 20
        run: |
          mkdir -p ~/node-dl
          curl -sL --max-time 120 -o ~/node-dl/node.tar.gz \
            https://nodejs.org/dist/v20.18.0/node-v20.18.0-darwin-arm64.tar.gz
          cd ~/node-dl
          tar xzf node.tar.gz
          ls -la node-v20.18.0-darwin-arm64/bin/node

      - name: Cache openFrameworks
        id: cache-of
        uses: actions/cache@v4
        with:
          path: ~/of
          key: of-0.12.1-macos-${{ runner.arch }}

      - name: Download openFrameworks 0.12.1
        if: steps.cache-of.outputs.cache-hit != 'true'
        run: |
          cd ~
          curl -sL -o of.tar.gz https://github.com/openframeworks/openFrameworks/releases/download/0.12.1/of_v0.12.1_osx_release.tar.gz
          tar xzf of.tar.gz
          mv of_v0.12.1_osx_release of
          rm of.tar.gz

      - name: Symlink oscope-of into oF tree
        run: |
          ln -sf "$GITHUB_WORKSPACE/oscope-of" ~/of/apps/myApps/oscope-of

      - name: Build oscope-of (Release)
        run: |
          cd ~/of/apps/myApps/oscope-of
          make OF_ROOT=$HOME/of -j4 Release

      - name: Build launcher (universal)
        run: |
          cd launcher
          chmod +x build.sh 2>/dev/null || true
          if [ -f build.sh ]; then
            bash build.sh || true
          else
            xcodebuild -scheme AVLiveLauncher -configuration Release \
              -destination 'platform=macOS' \
              -derivedDataPath build ARCHS='arm64 x86_64' || true
          fi
          ls -la build/ 2>/dev/null || true

      - name: Verify binary
        run: |
          ls -la "$GITHUB_WORKSPACE/oscope-of/bin/oscope-of.app/Contents/MacOS/" || true
          file "$GITHUB_WORKSPACE/oscope-of/bin/oscope-of.app/Contents/MacOS/oscope-of" || true

      - name: Bundle libusb into oscope-of.app + data/
        run: |
          cd "$GITHUB_WORKSPACE/oscope-of/bin"
          mkdir -p oscope-of.app/Contents/Frameworks oscope-of.app/Contents/Resources
          # Copie data/ dans Resources
          cp -r data oscope-of.app/Contents/Resources/
          # Embarque libusb dans Frameworks et réécrit le rpath
          BIN=oscope-of.app/Contents/MacOS/oscope-of
          # Trouve le chemin du libusb actuellement linké
          OLD_LIB=$(otool -L "$BIN" | awk '/libusb/{print $1; exit}')
          if [ -n "$OLD_LIB" ] && [ -f "$OLD_LIB" ]; then
            cp -L "$OLD_LIB" oscope-of.app/Contents/Frameworks/libusb-1.0.0.dylib
            install_name_tool -change "$OLD_LIB" \
              "@executable_path/../Frameworks/libusb-1.0.0.dylib" "$BIN"
            echo "libusb bundled : $OLD_LIB → @executable_path/.."
            otool -L "$BIN" | head -10
          else
            echo "warning: libusb not found in linker output"
            otool -L "$BIN" | head -10
          fi

      - name: Stage DMG payload
        run: |
          cd "$GITHUB_WORKSPACE"
          mkdir -p dist payload
          # 1. oscope-of.app (visualizer)
          cp -R oscope-of/bin/oscope-of.app payload/
          # 2. AVLiveLauncher.app si build OK
          if [ -d launcher/build/Release/AVLiveLauncher.app ]; then
            cp -R launcher/build/Release/AVLiveLauncher.app payload/
          elif [ -d launcher/build/Build/Products/Release/AVLiveLauncher.app ]; then
            cp -R launcher/build/Build/Products/Release/AVLiveLauncher.app payload/
          fi
          # 3. sound_algo source (pour sclang)
          cp -R sound_algo payload/
          # 4. SuperCollider.app bundled
          cp -R ~/sc-extracted/SuperCollider.app payload/
          # 5. node binary standalone (~70 MB)
          mkdir -p payload/runtime
          cp ~/node-dl/node-v20.18.0-darwin-arm64/bin/node payload/runtime/node
          chmod +x payload/runtime/node
          # 6. INSTALL.txt avec prérequis et marche à suivre
          cat > payload/INSTALL.txt <<'EOF'
          AV-Live ${{ github.ref_name }} — DMG TOUT-INCLUS
          ================================================

          Ce paquet contient TOUT le nécessaire (rien à installer en plus) :
            - oscope-of.app           visualizer (libusb bundled)
            - AVLiveLauncher.app      menubar coordinateur
            - SuperCollider.app       moteur audio 3.14 universel
            - sound_algo/             1099 SynthDef + 345 tracks
            - runtime/node            Node.js 20 standalone pour web UI
            - INSTALL.txt             ce fichier

          INSTALLATION :
            1. Glissez le contenu du DMG dans un dossier (ex: ~/AV-Live/)
               ou directement dans /Applications pour les .app
            2. Premier lancement : clic-droit sur l'app > Ouvrir
               (Gatekeeper unsigned, normal pour binaire open-source)
            3. AVLiveLauncher démarre tout automatiquement :
                 sclang (moteur audio) + oscope-of (visu) + node (web :3000)

          UTILISATION :
            Touches 1-9, 0     -> 10 demoparties principales
            Touches F6-F10     -> 5 demoparties additionnelles
            Touche q / Esc     -> mode live (sphere wave 3D)
            Touches azertyuiop -> 10 backgrounds scènes
            Touches s d f g h... -> 17 paramètres FX live
            Flèches haut/bas   -> ajuste valeur paramètre sélectionné

          Hantek 6022BL (oscilloscope USB) supporté en option pour piloter
          la visualisation depuis l'audio physique. Sans le scope, oscope-of
          tourne quand même avec le signal OSC depuis sclang.

          Documentation : https://github.com/electron-rare/AV-Live
          EOF

          create-dmg \
            --volname "AV-Live ${{ github.ref_name }}" \
            --window-pos 200 120 \
            --window-size 700 480 \
            --icon-size 90 \
            --icon "oscope-of.app" 130 180 \
            --icon "AVLiveLauncher.app" 280 180 \
            --icon "sound_algo" 430 180 \
            --icon "INSTALL.txt" 580 180 \
            --app-drop-link 350 360 \
            "dist/AV-Live-${{ github.ref_name }}.dmg" \
            payload/ \
          || true
          # Fallback tar.gz si create-dmg fail
          if [ ! -f "dist/AV-Live-${{ github.ref_name }}.dmg" ]; then
            tar czf "dist/AV-Live-${{ github.ref_name }}.tar.gz" -C payload .
          fi
          ls -la dist/ payload/

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: AV-Live-macOS
          path: dist/*

      - name: Create GitHub Release
        if: startsWith(github.ref, 'refs/tags/v')
        uses: softprops/action-gh-release@v2
        with:
          files: dist/*
          generate_release_notes: true
          body: |
            # AV-Live ${{ github.ref_name }} — DMG tout-inclus

            Build automatique macOS (Apple Silicon). **Aucune dépendance à
            installer**, tout est bundlé dans le DMG.

            ## Contenu

            - `oscope-of.app` — visualizer (41 bg, 15 demoparties, 35 modèles 3D, libusb bundled)
            - `AVLiveLauncher.app` — menubar coordinateur
            - `SuperCollider.app` — moteur audio 3.14 universel
            - `sound_algo/` — 1099 SynthDef + 345 tracks SC
            - `runtime/node` — Node.js 20 standalone
            - `INSTALL.txt`

            ## Installation

            1. Téléchargez `AV-Live-${{ github.ref_name }}.dmg`
            2. Glissez le contenu dans `~/AV-Live/` ou `/Applications`
            3. **Premier lancement** : clic-droit sur l'app > Ouvrir (Gatekeeper non signé)
            4. AVLiveLauncher démarre tout automatiquement

            **Note** : binaires non signés Apple Developer. Avertissement Gatekeeper attendu, c'est normal.
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
