name: build

on:
  workflow_dispatch:
  push:
    branches: [master]
    paths-ignore:
      - "**.md"
      - ".gitignore"
      - "docs/*"
  pull_request:
    branches: [master]
    paths-ignore:
      - "**.md"
      - ".gitignore"
      - "docs/*"
  release:
    types: [published]

jobs:
  msvc:
    name: Windows ${{ matrix.arch }} ${{ matrix.build_type }} (${{ matrix.portable }})
    runs-on: windows-2022
    strategy:
      matrix:
        arch: [x86, x86_64]
        build_type: [Debug, Release]
        portable: [Portable, Non-Portable]
        exclude:
          - build_type: Debug
            portable: Portable
        include:
          - arch: x86
            platform: Win32
          - arch: x86_64
            platform: x64

    steps:
      - uses: actions/checkout@v3

      - name: Add msbuild to PATH
        uses: microsoft/setup-msbuild@v1.1

      - name: Create Build Environment
        run: cmake -E make_directory ${{ github.workspace }}/build

      - name: Configure CMake
        shell: bash
        working-directory: ${{ github.workspace }}/build
        run: |
          OPTIONS="-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=bin"
          if [ "${{ matrix.portable }}" == "Portable" ]; then
            OPTIONS+=" -DBuildPortableVersion=ON"
          else
            OPTIONS+=" -DBuildPortableVersion=OFF"
          fi
          OPTIONS+=" -DBuildJK2SPEngine=ON -DBuildJK2SPGame=ON -DBuildJK2SPRdVanilla=ON"
          cmake $GITHUB_WORKSPACE -A ${{ matrix.platform }} $OPTIONS

      - name: Build
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --build . --config ${{ matrix.build_type }} -j $NUMBER_OF_PROCESSORS

      - name: Install
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --install . --config ${{ matrix.build_type }}

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJK-windows-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{ github.workspace }}/build/bin/JediAcademy
          if-no-files-found: error

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJO-windows-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{ github.workspace }}/build/bin/JediOutcast
          if-no-files-found: error

  ubuntu:
    name: Ubuntu ${{ matrix.arch }} ${{ matrix.build_type }} (${{ matrix.portable }})
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        arch: [x86, x86_64]
        build_type: [Debug, Release]
        portable: [Non-Portable]

    steps:
      - uses: actions/checkout@v3

      - name: Create Build Environment
        run: |
          if [ ${{ matrix.arch }} == "x86" ]; then
            sudo dpkg --add-architecture i386
            sudo apt-get -qq update
            sudo apt-get -y install aptitude
            sudo apt-get -y install gcc-multilib g++-multilib ninja-build
            sudo apt-get -y install --allow-downgrades libpcre2-8-0:i386 libjpeg-dev:i386 libpng-dev:i386 libcurl4-openssl-dev:i386
            sudo aptitude -y install libglib2.0-dev:i386 libsdl2-dev:i386
          else
            sudo apt-get -qq update
            sudo apt-get install libjpeg-dev libpng-dev zlib1g-dev libsdl2-dev
          fi
          cmake -E make_directory ${{ github.workspace }}/build

      - name: Configure CMake
        shell: bash
        working-directory: ${{ github.workspace }}/build
        run: |
          OPTIONS="-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install"
          if [ "${{ matrix.portable }}" == "Portable" ]; then
            OPTIONS+=" -DUseInternalLibs=ON -DBuildPortableVersion=ON"
          else
            OPTIONS+=" -DUseInternalLibs=OFF -DBuildPortableVersion=OFF"
          fi
          if [ ${{ matrix.arch }} == "x86" ]; then
            OPTIONS+=" -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchains/linux-i686.cmake"
          fi
          OPTIONS+=" -DBuildJK2SPEngine=ON -DBuildJK2SPGame=ON -DBuildJK2SPRdVanilla=ON"
          cmake $GITHUB_WORKSPACE $OPTIONS

      - name: Build
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --build . -j $(nproc)

      - name: Install
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --install .

      - name: Create OpenJK binary archive
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/install/JediAcademy
        shell: bash
        run: tar -czvf OpenJK-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz *

      - name: Create OpenJO binary archive
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/install/JediOutcast
        shell: bash
        run: tar -czvf OpenJO-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz *

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJK-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{github.workspace}}/install/JediAcademy/OpenJK-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz
          if-no-files-found: error

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJO-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{github.workspace}}/install/JediOutcast/OpenJO-linux-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz
          if-no-files-found: error

  macos:
    name: macOS ${{ matrix.arch }} ${{ matrix.build_type }} (${{ matrix.portable}})
    runs-on: ${{ matrix.runner }}
    strategy:
      fail-fast: false
      matrix:
        runner: [macos-12, macos-14]
        build_type: [Debug, Release]
        portable: [Non-Portable]
        include:
          - runner: macos-12
            arch: x86_64
          - runner: macos-14
            arch: arm64

    steps:
      - uses: actions/checkout@v3

      - name: Create Build Environment
        run: |
          brew install zlib libjpeg libpng sdl2
          cmake -E make_directory ${{ github.workspace }}/build

      - name: Configure CMake
        shell: bash
        working-directory: ${{ github.workspace }}/build
        run: |
          OPTIONS="-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install"
          if [ "${{ matrix.portable }}" == "Portable" ]; then
            OPTIONS+=" -DUseInternalLibs=ON -DBuildPortableVersion=ON"
          else
            OPTIONS+=" -DUseInternalLibs=OFF -DBuildPortableVersion=OFF"
          fi
          OPTIONS+=" -DBuildJK2SPEngine=ON -DBuildJK2SPGame=ON -DBuildJK2SPRdVanilla=ON"
          cmake $GITHUB_WORKSPACE $OPTIONS

      - name: Build
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --build . -j $(getconf _NPROCESSORS_ONLN)

      - name: Install
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/build
        shell: bash
        run: cmake --install .

      - name: Create OpenJK binary archive
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/install/JediAcademy
        shell: bash
        run: |
          chmod +x openjk.${{ matrix.arch }}.app/Contents/MacOS/openjk.${{ matrix.arch }}
          tar -czvf openjk-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz *

      - name: Create OpenJO binary archive
        if: ${{ matrix.build_type == 'Release' }}
        working-directory: ${{ github.workspace }}/install/JediOutcast
        shell: bash
        run: |
          chmod +x openjo_sp.${{ matrix.arch }}.app/Contents/MacOS/openjo_sp.${{ matrix.arch }}
          tar -czvf openjo_sp-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz *

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJK-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{ github.workspace }}/install/JediAcademy/openjk-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz
          if-no-files-found: error

      - uses: actions/upload-artifact@v3
        if: ${{ matrix.build_type == 'Release' }}
        with:
          name: OpenJO-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}
          path: ${{ github.workspace }}/install/JediOutcast/openjo_sp-macos-${{ matrix.arch }}-${{ matrix.build_type }}-${{ matrix.portable }}.tar.gz
          if-no-files-found: error

  create-latest:
    if: github.event_name == 'push' && github.ref == 'refs/heads/master'
    needs: [msvc, ubuntu, macos]
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Download Artifacts
        uses: actions/download-artifact@v3

      - name: Create binary archives
        run: |
          7z a -r OpenJK-windows-x86.zip ./OpenJK-windows-x86-Release-Non-Portable/* '-x!msvcp*.*' '-x!vcruntime*.*' '-x!concrt*.*'
          7z a -r OpenJK-windows-x86_64.zip ./OpenJK-windows-x86_64-Release-Non-Portable/* '-x!msvcp*.*' '-x!vcruntime*.*' '-x!concrt*.*'
          mv ./OpenJK-linux-x86-Release-Non-Portable/* OpenJK-linux-x86.tar.gz
          mv ./OpenJK-linux-x86_64-Release-Non-Portable/* OpenJK-linux-x86_64.tar.gz
          mv ./OpenJK-macos-x86_64-Release-Non-Portable/* OpenJK-macos-x86_64.tar.gz
          mv ./OpenJK-macos-arm64-Release-Non-Portable/* OpenJK-macos-arm64.tar.gz

          7z a -r OpenJO-windows-x86.zip ./OpenJO-windows-x86-Release-Non-Portable/* '-x!msvcp*.*' '-x!vcruntime*.*' '-x!concrt*.*'
          7z a -r OpenJO-windows-x86_64.zip ./OpenJO-windows-x86_64-Release-Non-Portable/* '-x!msvcp*.*' '-x!vcruntime*.*' '-x!concrt*.*'
          mv ./OpenJO-linux-x86-Release-Non-Portable/* OpenJO-linux-x86.tar.gz
          mv ./OpenJO-linux-x86_64-Release-Non-Portable/* OpenJO-linux-x86_64.tar.gz
          mv ./OpenJO-macos-x86_64-Release-Non-Portable/* OpenJO-macos-x86_64.tar.gz
          mv ./OpenJO-macos-arm64-Release-Non-Portable/* OpenJO-macos-arm64.tar.gz

      - name: Create latest build
        uses: marvinpinto/action-automatic-releases@latest
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          automatic_release_tag: "latest"
          prerelease: false
          title: Latest Build
          files: |
            *.zip
            *.tar.gz

  create-release:
    if: github.event_name == 'release'
    needs: [msvc, ubuntu, macos]
    runs-on: ubuntu-22.04

    strategy:
      matrix:
        include:
          - artifact_dir: OpenJK-windows-x86-Release-Non-Portable/JediAcademy
            artifact_name: OpenJK-windows-x86.zip
            zip: true

          - artifact_dir: OpenJK-windows-x86_64-Release-Non-Portable/JediAcademy
            artifact_name: OpenJK-windows-x86_64.zip
            zip: true

          - artifact_dir: OpenJK-linux-x86-Release-Non-Portable
            artifact_name: OpenJK-linux-x86.tar.gz
            zip: false

          - artifact_dir: OpenJK-linux-x86_64-Release-Non-Portable
            artifact_name: OpenJK-linux-x86_64.tar.gz
            zip: false

          - artifact_dir: OpenJK-macos-x86_64-Release-Non-Portable
            artifact_name: OpenJK-macos-x86_64.tar.gz
            zip: false

          - artifact_dir: OpenJK-macos-arm64-Release-Non-Portable
            artifact_name: OpenJK-macos-arm64.tar.gz
            zip: false

          - artifact_dir: OpenJO-windows-x86-Release-Non-Portable/JediOutcast
            artifact_name: OpenJO-windows-x86.zip
            zip: true

          - artifact_dir: OpenJO-windows-x86_64-Release-Non-Portable/JediOutcast
            artifact_name: OpenJO-windows-x86_64.zip
            zip: true

          - artifact_dir: OpenJO-linux-x86-Release-Non-Portable
            artifact_name: OpenJO-linux-x86.tar.gz
            zip: false

          - artifact_dir: OpenJO-linux-x86_64-Release-Non-Portable
            artifact_name: OpenJO-linux-x86_64.tar.gz
            zip: false

          - artifact_dir: OpenJO-macos-x86_64-Release-Non-Portable
            artifact_name: OpenJO-macos-x86_64.tar.gz
            zip: false

          - artifact_dir: OpenJO-macos-arm64-Release-Non-Portable
            artifact_name: OpenJO-macos-arm64.tar.gz
            zip: false

    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Download Artifacts
        uses: actions/download-artifact@v3

      - name: Create archive
        run: |
          if [ "${{ matrix.zip }}" == "true" ]; then
            7z a -r ${{ matrix.artifact_name }} ./${{ matrix.artifact_dir }}/* '-x!msvcp*.*' '-x!vcruntime*.*' '-x!concrt*.*'
          else
            mv ./${{ matrix.artifact_dir }}/* ${{ matrix.artifact_name }}
          fi

      - name: Upload archives
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          tag: ${{ github.ref }}
          overwrite: true
          file: ${{ matrix.artifact_name }}
