name: Build

on:
  push:
    branches: ["*"]
  pull_request:
  workflow_dispatch:

env:
  BUILD_TYPE: Release

jobs:

  # Windows build
  win:
    runs-on: windows-2022
    name: 🪟 Windows MINGW64
    defaults:
      run:
        shell: msys2 {0}
    env:
      CCACHE_DIR:      "${{ github.workspace }}/.ccache"
      CCACHE_MAXSIZE:  "1000M"
      CCACHE_COMPRESS: "true"
    steps:
    - name: 🧰 Checkout
      uses: actions/checkout@v3
      with:
        submodules: recursive

    - name: 📜 Prepare Cache
      id:    prep-ccache
      shell: bash
      run: |
        mkdir -p "${CCACHE_DIR}"
        echo "::set-output name=dir::$CCACHE_DIR"

    - name: 📜 Restore ccache
      uses:  actions/cache@v3
      id:    cache-ccache
      with:
        path: |
          ${{ steps.prep-ccache.outputs.dir }}
        key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
        restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build

    - name: 📜 Restore CMakeCache
      uses:  actions/cache@v3
      with:
        path: |
          build/CMakeCache.txt
        key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}

    - name: 🟦 Install msys2
      uses: msys2/setup-msys2@v2
      with:
        msystem: mingw64
        pacboy: >-
          gcc:p
          lld:p
          cmake:p
          make:p
          ccache:p
          glfw:p
          file:p
          mbedtls:p
          python:p
          freetype:p
          dlfcn:p

    - name: ⬇️ Install dependencies
      run: |
        curl --proto '=https' --tlsv1.2 -sSf https://win.rustup.rs > rustup-init.exe
        ./rustup-init.exe -y --default-host=x86_64-pc-windows-gnu --default-toolchain=none
        rm rustup-init.exe
        $USERPROFILE/.cargo/bin/rustup.exe target add x86_64-pc-windows-gnu
        $USERPROFILE/.cargo/bin/rustup.exe default nightly

    - name: 🛠️ Build
      run: |
        mkdir -p build
        cd build
        # Get path to mingw python library
        PYTHON_LIB_NAME=$(pkg-config --libs-only-l python3 | sed 's/^-l//' | sed 's/ //')
        PYTHON_LIB_PATH=$(cygpath -m $(which lib${PYTHON_LIB_NAME}.dll))

        cmake -G "MinGW Makefiles"                \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE          \
          -DCMAKE_INSTALL_PREFIX="$PWD/install"   \
          -DCREATE_PACKAGE=ON                     \
          -DPython_LIBRARY="$PYTHON_LIB_PATH"     \
          -DCMAKE_C_COMPILER_LAUNCHER=ccache      \
          -DCMAKE_CXX_COMPILER_LAUNCHER=ccache    \
          -DCMAKE_C_FLAGS="-fuse-ld=lld"          \
          -DCMAKE_CXX_FLAGS="-fuse-ld=lld"        \
          -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache   \
          -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
          -DRUST_PATH="$USERPROFILE/.cargo/bin/"  \
          ..
        mingw32-make -j4 install
        cpack

    - name: ⬆️ Upload Portable ZIP
      uses: actions/upload-artifact@v3
      with:
        name: Windows Portable
        path: |
          build/install/*

    - name: ⬆️ Upload Windows Installer
      uses: actions/upload-artifact@v3
      with:
        name: Windows Installer
        path: |
          build/*.msi

  # MacOS build
  macos:
    runs-on: macos-11
    name: 🍎 macOS 11.0
    steps:

    - name: 🧰 Checkout
      uses: actions/checkout@v3
      with:
        submodules: recursive
        
    - name: 📜 Restore ccache
      uses: actions/cache@v3
      with:
        path: |
          ~/Library/Caches/ccache
        key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
        restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build

        
    - name: 📜 Restore CMakeCache
      uses: actions/cache@v3
      with:
        path: |
          build/CMakeCache.txt
        key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}

    - name: ⬇️ Install dependencies
      run: |
        brew bundle --no-lock --file dist/Brewfile

    - name: 🛠️ Build
      run: |
        mkdir -p build
        cd build
        CC=$(brew --prefix gcc@12)/bin/gcc-12     \
        CXX=$(brew --prefix gcc@12)/bin/g++-12    \
        OBJC=$(brew --prefix llvm)/bin/clang      \
        OBJCXX=$(brew --prefix llvm)/bin/clang++  \
        PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig":"$(brew --prefix)/lib/pkgconfig" \
        MACOSX_DEPLOYMENT_TARGET="10.15"          \
        cmake                                     \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE          \
          -DCREATE_BUNDLE=ON                      \
          -DCREATE_PACKAGE=ON                     \
          -DCMAKE_C_COMPILER_LAUNCHER=ccache      \
          -DCMAKE_CXX_COMPILER_LAUNCHER=ccache    \
          -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache   \
          -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
          ..
        make -j4 package

    - name: ⬆️ Upload DMG
      uses: actions/upload-artifact@v3
      with:
        name: macOS DMG
        path: build/*.dmg

  # Linux build
  linux:
    runs-on: ubuntu-22.04
    name: 🐧 Ubuntu 22.04
    steps:

      - name: 🧰 Checkout
        uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: 📜 Restore cache
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/ccache
          key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
          restore-keys: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build
          
      - name: 📜 Restore other caches
        uses: actions/cache@v3
        with:
          path: |
            build/CMakeCache.txt
            .flatpak-builder
          key: ${{ runner.os }}-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
          
      - name: ⬇️ Install dependencies
        run: |
          sudo rm -rf /usr/share/dotnet
          sudo rm -rf /opt/ghc
          sudo rm -rf "/usr/local/share/boost"
          sudo rm -rf "$AGENT_TOOLSDIRECTORY"

          sudo apt update
          sudo bash dist/get_deps_debian.sh
          
          sudo apt install -y python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse
          sudo wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O /usr/local/bin/appimagetool
          sudo chmod +x /usr/local/bin/appimagetool
          sudo pip3 install appimage-builder==1.0.0

          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh
          sh rustup-init.sh -y --default-toolchain none
          rm rustup-init.sh
          $HOME/.cargo/bin/rustup install nightly
          $HOME/.cargo/bin/rustup target add x86_64-unknown-linux-gnu
          $HOME/.cargo/bin/rustup default nightly

      - name: 🛠️ Build
        run: |
          mkdir -p build
          cd build
          CC=gcc-12 CXX=g++-12 cmake                  \
            -DCMAKE_BUILD_TYPE=$BUILD_TYPE            \
            -DCMAKE_INSTALL_PREFIX="/usr" 	      \
            -DCMAKE_C_COMPILER_LAUNCHER=ccache        \
            -DCMAKE_CXX_COMPILER_LAUNCHER=ccache      \
            -DCMAKE_C_FLAGS="-fuse-ld=lld"            \
            -DCMAKE_CXX_FLAGS="-fuse-ld=lld"          \
            -DCMAKE_OBJC_COMPILER_LAUNCHER=ccache   \
            -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache \
            -DRUST_PATH="$HOME/.cargo/bin/"           \
            ..
          make -j 4 install DESTDIR=AppDir

      - name: 📜 Set version variable
        run: |
          echo "version=`cat VERSION`" >> $GITHUB_ENV

      #- name: 📦 Bundle Flatpak
      #  run: |
      #    sudo apt install flatpak flatpak-builder
      #    flatpak --user remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
      #    flatpak --user install -y flathub org.freedesktop.Platform//20.08
      #    flatpak --user install -y flathub org.freedesktop.Sdk//20.08
      #    flatpak-builder --jobs=4 --repo=imhex _flatpak dist/net.werwolv.ImHex.yaml --ccache --keep-build-dirs
      #    flatpak build-bundle imhex imhex.flatpak net.werwolv.ImHex stable

      - name: 📦 Bundle DEB
        run: |
          cp -r build/DEBIAN build/AppDir
          dpkg-deb --build build/AppDir
          mv build/AppDir.deb imhex-${{env.version}}.deb
          rm -rf build/AppDir/DEBIAN

      - name: 📦 Bundle AppImage
        run: |
          cd build
          appimage-builder --recipe ../dist/AppImageBuilder.yml
          mv ImHex-AppImage-x86_64.AppImage ../imhex-${{env.version}}.AppImage
          cd ..

      #- name: ⬆️ Upload Flatpak
      #  uses: actions/upload-artifact@v3
      #  with:
      #    name: Linux Flatpak
      #    path: |
      #      imhex.flatpak

      - name: ⬆️ Upload DEB
        uses: actions/upload-artifact@v3
        with:
          name: Linux DEB (Ubuntu 22.04)
          path: '*.deb'

      - name: ⬆️ Upload AppImage
        uses: actions/upload-artifact@v3
        with:
          name: Linux AppImage
          path: '*.AppImage'

  archlinux-build:
    name: 🐧 ArchLinux
    runs-on: ubuntu-latest
    
    container:
      image: archlinux:base-devel

    steps:
      - name: ⬇️ Update all packages
        run: |
          pacman -Syyu --noconfirm

      - name: ⬇️ Install setup dependencies
        run: |
          pacman -Syu git ccache --noconfirm
          
      - name: 🧰 Checkout
        uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: ⬇️ Install ImHex dependencies
        run: |
          dist/get_deps_archlinux.sh --noconfirm

      - name: 📜 Restore ccache
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache/ccache
          key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ github.run_id }}
          restore-keys: archlinux-${{ secrets.CACHE_VERSION }}-build
        
      - name: 📜 Restore CMakeCache
        uses: actions/cache@v3
        with:
          path: |
            build/CMakeCache.txt
          key: archlinux-${{ secrets.CACHE_VERSION }}-build-${{ hashFiles('**/CMakeLists.txt') }}
      
      - name: 🛠️ Build
        run: |
          mkdir -p build
          cd build
          CC=gcc CXX=g++ cmake                  \
          -DCMAKE_BUILD_TYPE=$BUILD_TYPE            \
          -DCMAKE_INSTALL_PREFIX="/usr" 	      \
          -DCMAKE_C_COMPILER_LAUNCHER=ccache        \
          -DCMAKE_CXX_COMPILER_LAUNCHER=ccache      \
          -DCMAKE_C_FLAGS="-fuse-ld=lld"            \
          -DCMAKE_CXX_FLAGS="-fuse-ld=lld"          \
          -DRUST_PATH="$HOME/.cargo/bin/"           \
          ..
          make -j 4 install DESTDIR=installDir

      - name: 📜 Set version variable
        run: |
          echo "version=`cat VERSION`" >> $GITHUB_ENV
      
      - name: ✒️ Prepare PKGBUILD
        run: |
          cp dist/Arch/PKGBUILD build
          sed -i 's/%version%/${{env.version}}/g' build/PKGBUILD

    # makepkg doesn't want to run as root, so I had to chmod 777 all over
      - name: 📦 Package ArchLinux .pkg.tar.zst
        run: |
          cd build
          
          # the name is a small trick to make makepkg recognize it as the source
          # else, it would try to download the file from the release
          tar -cvf imhex-${{env.version}}-ArchLinux.pkg.tar.zst -C installDir .
          
          chmod -R 777 .
          
          sudo -u nobody makepkg

          # Remplace the old file
          rm imhex-${{env.version}}-ArchLinux.pkg.tar.zst
          mv *.pkg.tar.zst imhex-${{env.version}}-ArchLinux.pkg.tar.zst
      
      - name: ⬆️ Upload imhex-archlinux.pkg.tar.zst
        uses: actions/upload-artifact@v3
        with:
          name: ArchLinux .pkg.tar.zst
          path: |
            build/imhex-${{env.version}}-ArchLinux.pkg.tar.zst
            
