name: Release Draft

on:
  workflow_dispatch:

env:
  FLUTTER_VERSION: "3.13.9"
  APK_BUILD_DIR: "/tmp/build"

jobs:
  build:
    runs-on: ubuntu-20.04
    outputs:
      version: ${{ steps.get_version.outputs.version }}

    steps:
      - uses: actions/checkout@v4

      - name: Get version from pubspec.yaml
        id: get_version
        run: |
          VERSION=$(sed -n 's/^version: \([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' app/pubspec.yaml)
          echo "version=$VERSION" >> $GITHUB_OUTPUT

  build_apk:
    needs: build
    runs-on: ubuntu-22.04

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

      - name: Remove proprietary dependencies
        run: sh scripts/remove_proprietary_dependencies.sh

      - name: Copy files to env.APK_BUILD_DIR
        run: |
          mkdir -p $APK_BUILD_DIR
          cp -r . $APK_BUILD_DIR

      - name: Decode key.properties file
        working-directory: ${{ env.APK_BUILD_DIR }}
        env:
          ENCODED_STRING: ${{ secrets.ANDROID_KEY_PROPERTIES }}
        run: echo $ENCODED_STRING | base64 -di > app/android/key.properties

      - name: Decode android-keystore.jks file
        working-directory: ${{ env.APK_BUILD_DIR }}
        env:
          ENCODED_STRING: ${{ secrets.ANDROID_KEY_STORE }}
        run: mkdir secrets && echo $ENCODED_STRING | base64 -di > secrets/android-keystore.jks

      - name: Set up JDK 11
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '11'

      - name: Install Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}

      - name: Dependencies
        working-directory: ${{ env.APK_BUILD_DIR }}/app
        run: flutter pub get

      - name: Build APK
        working-directory: ${{ env.APK_BUILD_DIR }}/app
        run: flutter build apk

      - name: Upload APK
        uses: actions/upload-artifact@v3
        with:
          name: apk-result
          path: ${{ env.APK_BUILD_DIR }}/app/build/app/outputs/flutter-apk/app-release.apk

  build_tar_x86_64:
    needs: build
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y clang cmake libgtk-3-dev ninja-build libayatana-appindicator3-dev

      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          channel: "stable"

      - name: Dependencies
        working-directory: app
        run: flutter pub get

      - name: Compile linux
        working-directory: app
        run: flutter build linux

      - name: Create tar.gz archive
        run: |
          cd app/build/linux/x64/release/bundle
          tar -czvf ../../../../../result.tar.gz *

      - name: Upload tar.gz archive
        uses: actions/upload-artifact@v3
        with:
          name: tar-gz-x86-64-result
          path: ./app/*.tar.gz

  # Manage the Flutter version on the self-hosted runner manually!
  # Flutter currently doesn't provide Linux ARM64 binaries.
  build_tar_arm_64:
    needs: build
    runs-on: [ self-hosted, linux, arm64 ]

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y clang cmake libgtk-3-dev ninja-build libayatana-appindicator3-dev

      - name: Dependencies
        working-directory: app
        run: flutter pub get

      - name: Compile linux
        working-directory: app
        run: flutter build linux

      - name: Create tar.gz archive
        run: |
          cd app/build/linux/arm64/release/bundle
          tar -czvf ../../../../../result.tar.gz *

      - name: Upload tar.gz archive
        uses: actions/upload-artifact@v3
        with:
          name: tar-gz-arm-64-result
          path: ./app/*.tar.gz

  build_deb_x86_64:
    needs: build
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y clang cmake libgtk-3-dev ninja-build libayatana-appindicator3-dev

      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          channel: "stable"

      - name: Enable dart_distributor
        run: dart pub global activate flutter_distributor

      - name: Update PATH
        run: echo 'export PATH="$PATH:$HOME/.pub-cache/bin"' >> ~/.bashrc

      - name: Build deb package
        working-directory: app
        run: flutter_distributor package --platform linux --targets deb

      - name: Find deb file
        id: find_deb
        run: |
          VERSION=${{ needs.build.outputs.version }}
          DEB_PATH=$(find app/dist -name "localsend_app-$VERSION*-linux.deb")
          echo "deb_path=$DEB_PATH" >> $GITHUB_OUTPUT

      - name: Check if deb file exists
        id: check_file
        run: |
          if [[ ! -f "${{ steps.find_deb.outputs.deb_path }}" ]]; then
            echo "File not found: ${{ steps.find_deb.outputs.deb_path }}"
            exit 1
          fi

      - name: Upload deb file
        uses: actions/upload-artifact@v3
        with:
          name: deb-x86-64-result
          path: ${{ steps.find_deb.outputs.deb_path }}

  # Manage the Flutter version on the self-hosted runner manually!
  # Flutter currently doesn't provide Linux ARM64 binaries.
  build_deb_arm_64:
    needs: build
    runs-on: [ self-hosted, linux, arm64 ]

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y clang cmake libgtk-3-dev ninja-build libayatana-appindicator3-dev

      - name: Enable dart_distributor
        run: dart pub global activate flutter_distributor

      - name: Build deb package
        working-directory: app
        run: PATH="$PATH:$HOME/.pub-cache/bin" flutter_distributor package --platform linux --targets deb

      - name: Find deb file
        id: find_deb
        run: |
          VERSION=${{ needs.build.outputs.version }}
          DEB_PATH=$(find app/dist -name "localsend_app-$VERSION*-linux.deb")
          echo "deb_path=$DEB_PATH" >> $GITHUB_OUTPUT

      - name: Check if deb file exists
        id: check_file
        run: |
          if [[ ! -f "${{ steps.find_deb.outputs.deb_path }}" ]]; then
            echo "File not found: ${{ steps.find_deb.outputs.deb_path }}"
            exit 1
          fi

      # Remove this when: https://github.com/leanflutter/flutter_distributor/pull/150 is merged
      - name: Update Architecture
        run: |
          mkdir temp
          cd temp
          ar x ../${{ steps.find_deb.outputs.deb_path }}
          tar xJf control.tar.xz --overwrite
          sed -i '/Architecture:/c\Architecture: arm64' ./control
          tar cJf control.tar.xz control postinst postrm
          ar rcs ../${{ steps.find_deb.outputs.deb_path }} debian-binary control.tar.xz data.tar.xz

      - name: Upload deb file
        uses: actions/upload-artifact@v3
        with:
          name: deb-arm-64-result
          path: ${{ steps.find_deb.outputs.deb_path }}

  build_appimage_x86_64:
    needs: build
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y clang cmake libgtk-3-dev ninja-build libayatana-appindicator3-dev libfuse2

      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          channel: "stable"

      - name: Dependencies
        working-directory: app
        run: flutter pub get

      - name: Compile linux
        working-directory: app
        run: flutter build linux

      - name: Copy compiled linux files
        run: |
          mkdir AppDir
          cp -r app/build/linux/x64/release/bundle/* AppDir/

      - name: Copy logo to AppDir
        run: |
          mkdir -p AppDir/usr/share/icons/hicolor/32x32/apps
          cp app/assets/img/logo-32.png AppDir/usr/share/icons/hicolor/32x32/apps/localsend.png
          mkdir -p AppDir/usr/share/icons/hicolor/128x128/apps
          cp app/assets/img/logo-128.png AppDir/usr/share/icons/hicolor/128x128/apps/localsend.png
          mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
          cp app/assets/img/logo-256.png AppDir/usr/share/icons/hicolor/256x256/apps/localsend.png

      - name: Copy Recipe to correct location
        run: cp scripts/appimage/AppImageBuilder_x86_64.yml AppImageBuilder.yml

      - name: Build AppImage
        uses: AppImageCrafters/build-appimage@57c3bc6963f870ce3be103117de5b5e33ffbaeb6
        with:
          recipe: ./AppImageBuilder.yml

      - name: Upload AppImage file
        uses: actions/upload-artifact@v3
        with:
          name: appimage-x86-64-result
          path: ./*.AppImage

  build_windows_zip_x86_64:
    needs: build
    runs-on: windows-latest

    steps:
      - name: Fix long file paths
        run: git config --system core.longpaths true

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

      - uses: subosito/flutter-action@v2
        with:
          flutter-version: ${{ env.FLUTTER_VERSION }}
          channel: "stable"

      - name: Dependencies
        working-directory: app
        run: flutter pub get

      - name: Compile for Windows
        working-directory: app
        run: flutter build windows

      - name: Create empty settings.json
        working-directory: app
        run: echo {} > build/windows/runner/Release/settings.json

      - name: Zip compiled files
        working-directory: app
        run: Compress-Archive -Path build/windows/runner/Release/* -DestinationPath LocalSend.zip

      - name: Upload zip
        uses: actions/upload-artifact@v3
        with:
          name: windows-zip-x86-64-result
          path: app/LocalSend.zip

  release:
    needs:
      - build
      - build_apk
      - build_tar_x86_64
      - build_tar_arm_64
      - build_deb_x86_64
      - build_deb_arm_64
      - build_appimage_x86_64
      - build_windows_zip_x86_64
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v4

      - name: Draft release
        id: draft_release
        uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag: v${{ needs.build.outputs.version }}
          name: v${{ needs.build.outputs.version }}

      # APK
      - name: Download apk file
        uses: actions/download-artifact@v3
        with:
          name: apk-result
          path: apk-result

      - name: Copy apk file to root
        run: cp apk-result/*.apk result.apk

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.apk
          asset_name: LocalSend-${{ needs.build.outputs.version }}.apk
          asset_content_type: application/vnd.android.package-archive

      # TAR.GZ (x86_64)
      - name: Download tar.gz file
        uses: actions/download-artifact@v3
        with:
          name: tar-gz-x86-64-result
          path: tar-gz-x86-64-result

      - name: List files in tar.gz-directory
        run: ls -l tar-gz-x86-64-result

      - name: Copy tar.gz file to root
        run: cp tar-gz-x86-64-result/* result.tar.gz

      - name: Upload Release Asset (tar.gz)
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.tar.gz
          asset_name: LocalSend-${{ needs.build.outputs.version }}-linux-x86-64.tar.gz
          asset_content_type: application/gzip

      # TAR.GZ (arm_64)
      - name: Download tar.gz file
        uses: actions/download-artifact@v3
        with:
          name: tar-gz-arm-64-result
          path: tar-gz-arm-64-result

      - name: List files in tar.gz-directory
        run: ls -l tar-gz-arm-64-result

      - name: Copy tar.gz file to root
        run: cp tar-gz-arm-64-result/* result.tar.gz

      - name: Upload Release Asset (tar.gz)
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.tar.gz
          asset_name: LocalSend-${{ needs.build.outputs.version }}-linux-arm-64.tar.gz
          asset_content_type: application/gzip

      # DEB (x86_64)
      - name: Download deb file
        uses: actions/download-artifact@v3
        with:
          name: deb-x86-64-result
          path: deb-x86-64-result

      - name: Copy deb file to root
        run: cp deb-x86-64-result/*.deb result.deb

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.deb
          asset_name: LocalSend-${{ needs.build.outputs.version }}-linux-x86-64.deb
          asset_content_type: application/vnd.debian.binary-package

      # DEB (arm_64)
      - name: Download deb file
        uses: actions/download-artifact@v3
        with:
          name: deb-arm-64-result
          path: deb-arm-64-result

      - name: Copy deb file to root
        run: cp deb-arm-64-result/*.deb result.deb

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.deb
          asset_name: LocalSend-${{ needs.build.outputs.version }}-linux-arm-64.deb
          asset_content_type: application/vnd.debian.binary-package

      # APPIMAGE (x86_64)
      - name: Download AppImage file
        uses: actions/download-artifact@v3
        with:
          name: appimage-x86-64-result
          path: appimage-x86-64-result

      - name: List files in appimage-directory
        run: ls -l appimage-x86-64-result

      - name: Copy AppImage file to root
        run: |
          for file in appimage-x86-64-result/*; do
            if [[ $file == *.AppImage && $file != *.AppImage.zsync ]]; then
              cp "$file" result.AppImage
            fi
          done

      - name: Upload Release Asset (AppImage)
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.AppImage
          asset_name: LocalSend-${{ needs.build.outputs.version }}-linux-x86-64.AppImage
          asset_content_type: application/x-appimage

      # WINDOWS ZIP (x86_64)
      - name: Download windows zip file
        uses: actions/download-artifact@v3
        with:
          name: windows-zip-x86-64-result
          path: windows-zip-x86-64-result

      - name: Copy zip file to root
        run: cp windows-zip-x86-64-result/*.zip result.zip

      - name: Upload Release Asset
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.draft_release.outputs.upload_url }}
          asset_path: result.zip
          asset_name: LocalSend-${{ needs.build.outputs.version }}-windows-x86-64.zip
          asset_content_type: application/zip
