name: Build Release Artifacts

on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      job:
        description: 'Job to run (or all)'
        required: true
        default: 'all'
        type: choice
        options:
          - all
          - android
          - macos
          - windows
          - ios
          - linux
          - linux-arm64

permissions:
  contents: write

jobs:
  android:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'android'
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Java
      uses: actions/setup-java@v4
      with:
        distribution: 'zulu'
        java-version: '17'

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        flutter-version: '3.32.8'
        channel: 'stable'

    - name: Cache dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.pub-cache
          .dart_tool
          ~/.gradle/caches
          ~/.gradle/wrapper
        key: ${{ runner.os }}-deps-${{ hashFiles('**/pubspec.lock', '**/*.gradle*') }}
        restore-keys: |
          ${{ runner.os }}-deps-

    - name: Get dependencies
      run: flutter pub get

    - name: Decode keystore
      run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > android/app/release.keystore

    - name: Create key.properties
      run: |
        cat > android/key.properties << EOF
        storePassword=${{ secrets.KEYSTORE_PASSWORD }}
        keyPassword=${{ secrets.KEY_PASSWORD }}
        keyAlias=${{ secrets.KEY_ALIAS }}
        storeFile=release.keystore
        EOF

    - name: Build APK
      run: flutter build apk --release

    - name: Rename APK (release)
      if: github.event_name == 'release'
      run: mv build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/debrify-${{ github.event.release.tag_name }}.apk

    - name: Attach APK to GitHub Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: build/app/outputs/flutter-apk/debrify-${{ github.event.release.tag_name }}.apk
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload APK as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-android
        path: build/app/outputs/flutter-apk/app-release.apk

  macos:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'macos'
    runs-on: macos-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        flutter-version: '3.32.8'
        channel: 'stable'

    - name: Get dependencies
      run: flutter pub get

    - name: Build macOS app
      run: flutter build macos --release

    - name: Install create-dmg
      run: HOMEBREW_NO_AUTO_UPDATE=1 brew install create-dmg

    - name: Prepare DMG staging folder
      run: |
        cd build/macos/Build/Products/Release
        rm -rf dmg-root
        mkdir -p dmg-root
        cp -R debrify.app dmg-root/Debrify.app

    - name: Create DMG (release)
      if: github.event_name == 'release'
      run: |
        cd build/macos/Build/Products/Release
        create-dmg \
          --volname "Debrify" \
          --window-pos 200 120 \
          --window-size 520 360 \
          --icon-size 120 \
          --icon "Debrify.app" 120 180 \
          --app-drop-link 400 180 \
          debrify-${{ github.event.release.tag_name }}.dmg \
          dmg-root

    - name: Create DMG (manual)
      if: github.event_name == 'workflow_dispatch'
      run: |
        cd build/macos/Build/Products/Release
        create-dmg \
          --volname "Debrify" \
          --window-pos 200 120 \
          --window-size 520 360 \
          --icon-size 120 \
          --icon "Debrify.app" 120 180 \
          --app-drop-link 400 180 \
          debrify.dmg \
          dmg-root

    - name: Upload DMG to Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: build/macos/Build/Products/Release/debrify-${{ github.event.release.tag_name }}.dmg
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload DMG as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-macos
        path: build/macos/Build/Products/Release/debrify.dmg

  windows:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'windows'
    runs-on: windows-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        flutter-version: '3.32.8'
        channel: 'stable'

    - name: Enable Windows desktop
      run: flutter config --enable-windows-desktop

    - name: Get dependencies
      run: flutter pub get

    - name: Build Windows app
      run: flutter build windows --release

    - name: Install Inno Setup
      run: choco install innosetup --no-progress --yes

    - name: Build Windows installer
      shell: pwsh
      run: |
        $env:DEBRIFY_VERSION = '${{ github.event.release.tag_name || 'dev' }}'
        & "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" windows\installer.iss

    - name: Upload Windows installer to Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: build/windows/installer/debrify-${{ github.event.release.tag_name }}-setup.exe
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload Windows installer as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-windows
        path: build/windows/installer/debrify-dev-setup.exe

  ios:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'ios'
    runs-on: macos-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        flutter-version: '3.32.8'
        channel: 'stable'

    - name: Get dependencies
      run: flutter pub get

    - name: Build iOS (unsigned)
      run: flutter build ios --release --no-codesign

    - name: Create unsigned IPA (release)
      if: github.event_name == 'release'
      run: |
        cd build/ios/iphoneos
        mkdir -p Payload
        cp -R Runner.app Payload/
        zip -r debrify-${{ github.event.release.tag_name }}-unsigned.ipa Payload
        rm -rf Payload

    - name: Create unsigned IPA (manual)
      if: github.event_name == 'workflow_dispatch'
      run: |
        cd build/ios/iphoneos
        mkdir -p Payload
        cp -R Runner.app Payload/
        zip -r debrify-unsigned.ipa Payload
        rm -rf Payload

    - name: Upload IPA to Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: build/ios/iphoneos/debrify-${{ github.event.release.tag_name }}-unsigned.ipa
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload IPA as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-ios
        path: build/ios/iphoneos/debrify-unsigned.ipa

  linux:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'linux'
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Install Linux dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev

    - name: Setup Flutter
      uses: subosito/flutter-action@v2
      with:
        flutter-version: '3.32.8'
        channel: 'stable'

    - name: Enable Linux desktop
      run: flutter config --enable-linux-desktop

    - name: Get dependencies
      run: flutter pub get

    - name: Build Linux app
      run: flutter build linux --release

    - name: Create AppImage
      run: |
        # Download appimagetool
        wget -q https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
        chmod +x appimagetool-x86_64.AppImage

        # Create AppDir structure
        mkdir -p AppDir/usr/bin
        mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
        mkdir -p AppDir/usr/share/applications

        # Copy built app
        cp -r build/linux/x64/release/bundle/* AppDir/usr/bin/

        # Copy icon
        cp assets/app_icon.png AppDir/usr/share/icons/hicolor/256x256/apps/debrify.png
        cp assets/app_icon.png AppDir/debrify.png

        # Create desktop file
        cat > AppDir/debrify.desktop << 'EOF'
        [Desktop Entry]
        Name=Debrify
        Comment=Modern debrid companion with torrent search and playlist management
        Exec=debrify
        Icon=debrify
        Type=Application
        Categories=Utility;Network;
        EOF

        cp AppDir/debrify.desktop AppDir/usr/share/applications/

        # Create AppRun
        cat > AppDir/AppRun << 'EOF'
        #!/bin/bash
        SELF=$(readlink -f "$0")
        HERE=${SELF%/*}
        export PATH="${HERE}/usr/bin:${PATH}"
        export LD_LIBRARY_PATH="${HERE}/usr/bin/lib:${LD_LIBRARY_PATH}"
        exec "${HERE}/usr/bin/debrify" "$@"
        EOF
        chmod +x AppDir/AppRun

        # Build AppImage
        VERSION="${{ github.event.release.tag_name }}"
        if [ -z "$VERSION" ]; then VERSION="dev"; fi
        ARCH=x86_64 ./appimagetool-x86_64.AppImage --appimage-extract-and-run AppDir debrify-${VERSION}-x86_64.AppImage

    - name: Upload AppImage to Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: debrify-${{ github.event.release.tag_name }}-x86_64.AppImage
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload AppImage as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-linux
        path: debrify-dev-x86_64.AppImage

  linux-arm64:
    if: github.event_name == 'release' || github.event.inputs.job == 'all' || github.event.inputs.job == 'linux-arm64'
    runs-on: ubuntu-24.04-arm
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Install Linux dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev

    - name: Setup Flutter (manual for arm64)
      run: |
        # subosito/flutter-action doesn't support linux-arm64, install manually
        # Using stable tag - see https://github.com/subosito/flutter-action/issues/345
        git clone --depth 1 --branch 3.38.9 https://github.com/flutter/flutter.git $RUNNER_TEMP/flutter
        echo "$RUNNER_TEMP/flutter/bin" >> $GITHUB_PATH

    - name: Precache Flutter
      run: |
        flutter precache --linux
        flutter doctor -v

    - name: Enable Linux desktop
      run: flutter config --enable-linux-desktop

    - name: Get dependencies
      run: flutter pub get

    - name: Build Linux app
      run: flutter build linux --release

    - name: Create AppImage
      run: |
        # Download appimagetool for aarch64
        wget -q https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-aarch64.AppImage
        chmod +x appimagetool-aarch64.AppImage

        # Create AppDir structure
        mkdir -p AppDir/usr/bin
        mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
        mkdir -p AppDir/usr/share/applications

        # Copy built app (arm64 path)
        cp -r build/linux/arm64/release/bundle/* AppDir/usr/bin/

        # Copy icon
        cp assets/app_icon.png AppDir/usr/share/icons/hicolor/256x256/apps/debrify.png
        cp assets/app_icon.png AppDir/debrify.png

        # Create desktop file
        cat > AppDir/debrify.desktop << 'EOF'
        [Desktop Entry]
        Name=Debrify
        Comment=Modern debrid companion with torrent search and playlist management
        Exec=debrify
        Icon=debrify
        Type=Application
        Categories=Utility;Network;
        EOF

        cp AppDir/debrify.desktop AppDir/usr/share/applications/

        # Create AppRun
        cat > AppDir/AppRun << 'EOF'
        #!/bin/bash
        SELF=$(readlink -f "$0")
        HERE=${SELF%/*}
        export PATH="${HERE}/usr/bin:${PATH}"
        export LD_LIBRARY_PATH="${HERE}/usr/bin/lib:${LD_LIBRARY_PATH}"
        exec "${HERE}/usr/bin/debrify" "$@"
        EOF
        chmod +x AppDir/AppRun

        # Build AppImage
        VERSION="${{ github.event.release.tag_name }}"
        if [ -z "$VERSION" ]; then VERSION="dev"; fi

        # Note: appimagetool expects "arm_aarch64" not "aarch64"
        # See: https://github.com/AppImage/AppImageKit/issues/1163
        export ARCH=arm_aarch64
        ./appimagetool-aarch64.AppImage --appimage-extract-and-run AppDir debrify-${VERSION}-arm64.AppImage

    - name: Upload AppImage to Release
      if: github.event_name == 'release'
      uses: softprops/action-gh-release@v1
      with:
        files: debrify-${{ github.event.release.tag_name }}-arm64.AppImage
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Upload AppImage as artifact (manual)
      if: github.event_name == 'workflow_dispatch'
      uses: actions/upload-artifact@v4
      with:
        name: debrify-linux-arm64
        path: debrify-dev-arm64.AppImage
