name: Build Fladder

on:
  push:
    tags:
      - "v*"
    branches:
      - master
  pull_request:
    paths:
      - pubspec.yaml
      - .github/workflows/build.yml
      - .fvmrc
    types:
      - opened
      - reopened
  workflow_dispatch:

jobs:
  fetch-info:
    runs-on: ubuntu-latest
    outputs:
      version_name: ${{ steps.fetch.outputs.version_name }}
      flutter_version: ${{ steps.fetch.outputs.flutter_version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Fetch version name
        id: fetch
        run: |
          # Extract version_name from pubspec.yaml
          VERSION_NAME=$(grep '^version:' pubspec.yaml | cut -d ':' -f2 | cut -d '+' -f1 | tr -d ' ')
          echo "version_name=${VERSION_NAME}" >> "$GITHUB_OUTPUT"

          # Extract flutter_version from .fvmrc
          FLUTTER_VERSION=$(jq -r '.flutter' .fvmrc)
          echo "flutter_version=${FLUTTER_VERSION}" >> "$GITHUB_OUTPUT"

          # Print flutter version for logging
          echo "Flutter version: $FLUTTER_VERSION"
        shell: bash

  build-android:
    needs: [fetch-info]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Determine Build Type
        run: |
          if [[ "${{ startsWith(github.ref, 'refs/tags/v') }}" == "true" ]]; then
            echo "BUILD_MODE=release" >> $GITHUB_ENV
            echo "ARTIFACT_SUFFIX=release-signed" >> $GITHUB_ENV
            echo "AAB_PATH=productionRelease" >> $GITHUB_ENV
          else
            echo "BUILD_MODE=profile" >> $GITHUB_ENV
            echo "ARTIFACT_SUFFIX=production" >> $GITHUB_ENV
            echo "AAB_PATH=productionProfile" >> $GITHUB_ENV
          fi

      - name: Decode Keystore for release
        if: startsWith(github.ref, 'refs/tags/v')
        env:
          ENCODED_STRING: ${{ secrets.KEYSTORE_BASE_64 }}
          RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
          RELEASE_KEYSTORE_ALIAS: ${{ secrets.RELEASE_KEYSTORE_ALIAS }}
          RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
          GITHUB_RUN_NUMBER: ${{ github.run_number }}
        run: |
          echo "$ENCODED_STRING" | base64 -d > android/app/keystore.jks

          # Create the key.properties file
          cat > android/app/key.properties <<EOF
          storePassword=$RELEASE_KEYSTORE_PASSWORD
          keyPassword=$RELEASE_KEY_PASSWORD
          keyAlias=$RELEASE_KEYSTORE_ALIAS
          EOF

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: "zulu"
          java-version: "17"
          cache: "gradle"
          check-latest: true

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Get dependencies
        run: flutter pub get

      - name: Build Android APK and AAB
        run: |
          flutter build apk --${{ env.BUILD_MODE }} --build-number=${{github.run_number}} --flavor production
          flutter build appbundle --${{ env.BUILD_MODE }} --build-number=${{github.run_number}} --flavor production

      - name: Rename APK and AAB
        run: |
          mkdir -p build/app/outputs/android_artifacts
          mv build/app/outputs/flutter-apk/app-production-${{ env.BUILD_MODE }}.apk "build/app/outputs/android_artifacts/${{ env.ARTIFACT_SUFFIX }}.apk"
          mv build/app/outputs/bundle/${{ env.AAB_PATH }}/app-production-${{ env.BUILD_MODE }}.aab "build/app/outputs/android_artifacts/${{ env.ARTIFACT_SUFFIX }}.aab"

      - name: Archive Android artifacts
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-android
          path: build/app/outputs/android_artifacts/

  build-windows:
    runs-on: windows-latest
    needs: [fetch-info]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Get dependencies
        run: flutter pub get

      - name: Build Windows EXE
        run: flutter build windows --build-number=${{ github.run_number }}

      - name: Compile Inno Setup installer
        uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
        with:
          path: windows/windows_setup.iss
          options: /O+
        env:
          FLADDER_VERSION: ${{needs.fetch-info.outputs.version_name}}

      - name: Archive Windows portable artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-windows-portable
          path: build\windows\x64\runner\Release\

      - name: Archive Windows installer artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-windows-installer
          path: windows\Output\fladder_setup.exe

  build-ios:
    runs-on: macos-latest
    needs: [fetch-info]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Get dependencies
        run: flutter pub get

      - name: Build iOS app
        run: flutter build ipa --no-codesign --flavor production --build-number=${{ github.run_number }}

      - name: Create unsigned IPA
        run: |
          cd build/ios/archive/Runner.xcarchive/Products/Applications/
          mkdir Payload
          mv Runner.app Payload/
          zip -r iOS.ipa Payload

      - name: Archive iOS IPA artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-iOS
          path: build/ios/archive/Runner.xcarchive/Products/Applications/iOS.ipa

  build-macos:
    runs-on: macos-latest
    needs: [fetch-info]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Get dependencies
        run: flutter pub get

      - name: Build macOS app
        run: flutter build macos --flavor production --build-number=${{ github.run_number }}

      - name: Ensure correct app name casing
        run: |
          APP_DIR="build/macos/Build/Products/Release-production"
          mv "$APP_DIR/fladder.app" "$APP_DIR/Fladder.app"

      - name: Install create-dmg
        run: brew install create-dmg

      - name: Create DMG with custom background
        run: ./scripts/create_dmg.sh

      - name: Archive macOS artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-macOS
          path: build/macos/Build/Products/Release-production/macOS.dmg

  build-linux:
    runs-on: ubuntu-latest
    needs: [fetch-info]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Update build number in pubspec.yaml
        run: |
          sed -i -E 's/(version: [0-9]+\.[0-9]+\.[0-9]+\+)[0-9]+/\1${{ github.run_number }}/' pubspec.yaml

      - name: Get dependencies
        run: flutter pub get

      - name: Get packages
        run: |
          sudo apt-get update -y
          sudo apt-get install -y ninja-build libgtk-3-dev libmpv-dev patchelf cmake clang libfuse2

      - name: Build Linux app
        run: flutter build linux --release --build-number=${{ github.run_number }}

      - name: Fix RPATH
        run: |
          for lib in "build/linux/x64/release/bundle/lib"/*.so; do
            [[ -f "$lib" && -n "$(patchelf --print-rpath "$lib")" ]] && \
            patchelf --set-rpath '$ORIGIN' "$lib"
          done
          patchelf --set-rpath '$ORIGIN/lib' "build/linux/x64/release/bundle/Fladder"

      - name: Archive Linux artifact
        uses: actions/upload-artifact@v4
        with:
          name: fladder-linux
          path: build/linux/x64/release/bundle

      - name: Build AppImage
        run: |
          sed -i -E 's/(version:\s*)latest/\1${{needs.fetch-info.outputs.version_name}}/' AppImageBuilder.yml
          wget -O appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage
          chmod +x appimage-builder-x86_64.AppImage
          sudo mv appimage-builder-x86_64.AppImage /usr/local/bin/appimage-builder
          appimage-builder --recipe AppImageBuilder.yml

      - name: Archive Linux artifact
        uses: actions/upload-artifact@v4
        with:
          name: fladder-linux-appimage
          path: |
            Fladder_x86_64.AppImage
            Fladder_x86_64.AppImage.zsync

  build-linux-flatpak:
    name: "Flatpak"
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    needs: [fetch-info, build-linux]
    container:
      image: bilelmoussaoui/flatpak-github-actions:gnome-46
      options: --privileged
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1
        with:
          submodules: true

      - name: Download Artifacts Linux
        uses: actions/download-artifact@v4
        with:
          name: fladder-linux
          path: build/linux/x64/release/bundle

      - uses: flatpak/flatpak-github-actions/flatpak-builder@v6
        with:
          bundle: Fladder-Linux.flatpak
          manifest-path: flatpak/nl.jknaapen.fladder.yaml

      - name: Archive Linux Flatpak bundle
        uses: actions/upload-artifact@v4
        with:
          name: fladder-linux-flatpak
          path: Fladder-Linux.flatpak

  build-web:
    runs-on: ubuntu-latest
    needs: [fetch-info]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Set up Flutter
        uses: subosito/flutter-action@v2.19.0
        with:
          channel: "stable"
          flutter-version: ${{needs.fetch-info.outputs.flutter_version}}
          cache: true
          cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
          cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"

      - name: Get dependencies
        run: flutter pub get

      - name: Build web app
        run: |
          flutter build web --release --build-number=${{github.run_number}}

      - name: Archive web artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-web
          path: build/web

      - name: Build Github pages web
        if: startsWith(github.ref, 'refs/tags/v')
        run: flutter build web --base-href /${{ github.event.repository.name }}/ --release --build-number=$GITHUB_RUN_NUMBER

      - name: Archive web pages artifact
        uses: actions/upload-artifact@v4.0.0
        with:
          name: fladder-web-pages
          path: build/web

  create_release:
    name: Create Release
    needs:
      - fetch-info
      - build-android
      - build-windows
      - build-ios
      - build-macos
      - build-linux
      - build-linux-flatpak
      - build-web
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
      - name: Download Artifacts Android
        uses: actions/download-artifact@v4
        with:
          name: fladder-android
          path: fladder-android

      - name: Move Android
        run: |
          mv fladder-android/release-signed.apk Fladder-Android-${{needs.fetch-info.outputs.version_name}}.apk
          mv fladder-android/release-signed.aab Fladder-Android-${{needs.fetch-info.outputs.version_name}}.aab

      - name: Download Windows portable artifact
        uses: actions/download-artifact@v4
        with:
          name: fladder-windows-portable
          path: fladder-windows-portable

      - name: Compress Windows
        run: |
          cd fladder-windows-portable
          zip -r ../Fladder-Windows-${{needs.fetch-info.outputs.version_name}}.zip .

      - name: Download Windows installer artifact
        uses: actions/download-artifact@v4
        with:
          name: fladder-windows-installer
          path: fladder-windows-installer

      - name: Rename Windows installer
        run: mv fladder-windows-installer/fladder_setup.exe Fladder-Windows-${{needs.fetch-info.outputs.version_name}}-Setup.exe

      - name: Download Artifacts iOS
        uses: actions/download-artifact@v4
        with:
          name: fladder-iOS
          path: fladder-iOS

      - name: Move iOS
        run: mv fladder-iOS/iOS.ipa Fladder-iOS-${{needs.fetch-info.outputs.version_name}}.ipa

      - name: Download Artifacts macOS
        uses: actions/download-artifact@v4
        with:
          name: fladder-macOS
          path: fladder-macOS

      - name: Move macOS
        run: mv fladder-macOS/macOS.dmg Fladder-macOS-${{needs.fetch-info.outputs.version_name}}.dmg

      - name: Download Artifacts Linux
        uses: actions/download-artifact@v4
        with:
          name: fladder-linux
          path: fladder-linux

      - name: Compress Linux
        run: |
          cd fladder-linux
          zip -r ../Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.zip .

      - name: Download Artifacts Linux Flatpak
        uses: actions/download-artifact@v4
        with:
          name: fladder-linux-flatpak
          path: fladder-linux-flatpak

      - name: Move Linux Flatpak
        run: mv fladder-linux-flatpak/Fladder-Linux.flatpak Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.flatpak

      - name: Download Artifacts Linux AppImage
        uses: actions/download-artifact@v4
        with:
          name: fladder-linux-appimage
          path: fladder-linux-appimage

      - name: Move linux AppImages
        run: |
          mv fladder-linux-appimage/Fladder_x86_64.AppImage Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.AppImage
          mv fladder-linux-appimage/Fladder_x86_64.AppImage.zsync Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.AppImage.zsync

      - name: Download Artifacts Web
        uses: actions/download-artifact@v4
        with:
          name: fladder-web
          path: fladder-web

      - name: Compress Web
        run: |
          cd fladder-web
          zip -r ../Fladder-Web-${{needs.fetch-info.outputs.version_name}}.zip .

      - name: Release
        uses: softprops/action-gh-release@v2
        with:
          draft: true
          fail_on_unmatched_files: true
          generate_release_notes: true
          files: |
            Fladder-Android-${{needs.fetch-info.outputs.version_name}}.apk
            Fladder-Windows-${{needs.fetch-info.outputs.version_name}}-Setup.exe
            Fladder-Windows-${{needs.fetch-info.outputs.version_name}}.zip
            Fladder-iOS-${{needs.fetch-info.outputs.version_name}}.ipa
            Fladder-macOS-${{needs.fetch-info.outputs.version_name}}.dmg
            Fladder-Web-${{needs.fetch-info.outputs.version_name}}.zip
            Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.zip
            Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.flatpak
            Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.AppImage
            Fladder-Linux-${{needs.fetch-info.outputs.version_name}}.AppImage.zsync

  release_web:
    name: Release Web
    needs:
      - create_release
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4.1.1

      - name: Download Artifacts Web
        uses: actions/download-artifact@v4
        with:
          name: fladder-web
          path: build/web

      - name: Deploy to ghcr.io
        uses: mr-smithers-excellent/docker-build-push@v6
        with:
          image: fladder
          addLatest: true
          multiPlatform: true
          platform: linux/amd64,linux/arm64,linux/arm/v7
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Clean builds folder
        run: rm -rf build/web

      - name: Download Artifacts Web
        uses: actions/download-artifact@v4
        with:
          name: fladder-web-pages
          path: build/web

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./build/web
