name: 🔌 GDExtension
on:
  workflow_call:
    inputs:
      godot-cpp-ref:
        description: A tag, branch or commit hash in the godot-cpp repository.
        type: string
        default: 4.2
      limboai-ref:
        description: A tag, branch or commit hash in the LimboAI repository.
        type: string
        default: master
      test-build:
        description: Should we perform only a limited number of test builds?
        type: boolean
        default: false

  workflow_dispatch:
    inputs:
      godot-cpp-ref:
        description: A tag, branch or commit hash in the godot-cpp repository.
        type: string
        default: 4.2
      limboai-ref:
        description: A tag, branch or commit hash in the LimboAI repository.
        type: string
        default: master
      test-build:
        description: Should we perform only a limited number of test builds?
        type: boolean
        default: false

# Global Settings
env:
  SCONS_CACHE_LIMIT: 4096
  SCONSFLAGS: dev_build=no debug_symbols=no
  EM_VERSION: 3.1.45
  EM_CACHE_FOLDER: "emsdk-cache"

jobs:
  gdextension:
    runs-on: ${{ matrix.opts.runner }}
    name: ${{ matrix.opts.name }}
    outputs:
      name-prefix: ${{ steps.output-name-prefix.outputs.name-prefix }}
    strategy:
      fail-fast: false
      matrix:
        opts:
          - name: 🐧 Linux (x86_64, release)
            runner: ubuntu-20.04
            platform: linux
            target: template_release
            arch: x86_64
            should-build: true

          - name: 🐧 Linux (x86_64, debug)
            runner: ubuntu-20.04
            platform: linux
            target: editor
            arch: x86_64
            should-build: true

          - name: 🪟 Windows (x86_64, release)
            runner: windows-latest
            platform: windows
            target: template_release
            arch: x86_64
            should-build: true

          - name: 🪟 Windows (x86_64, debug)
            runner: windows-latest
            platform: windows
            target: editor
            arch: x86_64
            should-build: true

          - name: 🍎 macOS (universal, release)
            runner: macos-latest
            platform: macos
            target: template_release
            arch: universal
            should-build: true

          - name: 🍎 macOS (universal, debug)
            runner: macos-latest
            platform: macos
            target: editor
            arch: universal
            should-build: true

          - name: 🌐 Web (wasm32, release)
            runner: ubuntu-20.04
            platform: web
            target: template_release
            arch: wasm32
            should-build: true

          - name: 🌐 Web (wasm32, debug)
            runner: ubuntu-20.04
            platform: web
            target: template_debug
            arch: wasm32
            should-build: true

        exclude:
          - { opts: { should-build: false } }

    env:
      BIN: liblimboai.${{matrix.opts.platform}}.${{matrix.opts.target}}.${{matrix.opts.arch}}

    steps:
      - name: Clone godot-cpp
        uses: actions/checkout@v4
        with:
          repository: godotengine/godot-cpp
          fetch-tags: true
          path: godot-cpp
          ref: ${{ inputs.godot-cpp-ref }}

      - name: Clone LimboAI module
        uses: actions/checkout@v4
        with:
          path: limboai
          fetch-tags: true
          ref: ${{ inputs.limboai-ref }}

      # Inits GDEXTENSION_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
      - uses: ./limboai/.github/actions/init-version-gdext

      - name: Output NAME_PREFIX
        id: output-name-prefix
        run: echo "name-prefix=${NAME_PREFIX}" >> $GITHUB_OUTPUT

      - name: Set up Linux buildroot x86_64
        if: matrix.opts.platform == 'linux' && matrix.opts.arch == 'x86_64'
        run: |
          wget https://download.tuxfamily.org/godotengine/toolchains/linux/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
          tar -xjf x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2
          mv x86_64-godot-linux-gnu_sdk-buildroot buildroot
          cd buildroot
          ./relocate-sdk.sh
          cd ..

      - name: Set up Linux buildroot x86_32
        if: matrix.opts.platform == 'linux' && matrix.opts.arch == 'x86_32'
        run: |
          wget https://download.tuxfamily.org/godotengine/toolchains/linux/i686-godot-linux-gnu_sdk-buildroot.tar.bz2
          tar -xjf i686-godot-linux-gnu_sdk-buildroot.tar.bz2
          mv i686-godot-linux-gnu_sdk-buildroot buildroot
          cd buildroot
          ./relocate-sdk.sh
          cd ..

      - name: Set up Python 3.x
        if: matrix.opts.platform == 'windows' || matrix.opts.platform == 'macos'
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"
          architecture: "x64"

      - name: Set up Emscripten cache
        if: matrix.opts.platform == 'web'
        uses: actions/cache@v4
        with:
          path: ${{env.EM_CACHE_FOLDER}}
          key: ${{env.EM_VERSION}}-${{runner.os}}-libs

      - name: Set up Emscripten
        if: matrix.opts.platform == 'web'
        uses: mymindstorm/setup-emsdk@v14
        with:
          version: ${{env.EM_VERSION}}
          actions-cache-folder: ${{env.EM_CACHE_FOLDER}}

      - name: Verify Emscripten setup
        if: matrix.opts.platform == 'web'
        run: |
          emcc -v

      - name: Set up scons
        if: matrix.opts.platform == 'windows' || matrix.opts.platform == 'macos' || matrix.opts.platform == 'web'
        run: |
          python -c "import sys; print(sys.version)"
          python -m pip install scons==4.4.0
          python --version
          scons --version

      - name: Set up MSVC problem matcher on Windows
        if: matrix.opts.platform == 'windows'
        uses: ammaraskar/msvc-problem-matcher@master

      - name: Set up scons cache
        uses: actions/cache@v4
        with:
          path: ${{github.workspace}}/.scons_cache/
          key: ${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
          restore-keys: |
            ${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
            ${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}
            ${{env.BIN}}-${{inputs.godot-cpp-ref}}

      - name: Setup project structure for GDExtension
        shell: bash
        run: |
          bash ./limboai/gdextension/setup_gdextension.sh --copy-all
          echo "---"
          ls -l
          echo "---"
          ls -l -R ./demo/

      - name: Compilation
        shell: bash
        env:
          SCONS_CACHE: ${{github.workspace}}/.scons_cache/
        run: |
          PATH=${GITHUB_WORKSPACE}/buildroot/bin:$PATH
          scons platform=${{matrix.opts.platform}} target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} ${{env.SCONSFLAGS}}

      - name: Prepare artifact
        shell: bash
        run: |
          mkdir out
          mv demo/addons/ out/
          cp limboai/{README,LICENSE,LOGO_LICENSE}.md out/addons/limboai/
          cp -R limboai/demo/demo/ out/demo/
          cp limboai/demo/LICENSE_ASSETS.md out/demo/
          rm -f out/addons/limboai/bin/*.{exp,lib,pdb}
          echo "---"
          ls -R out/

      - name: Strip lib
        if: matrix.opts.platform != 'windows' && matrix.opts.platform != 'web'
        run: |
          ls -l -R out/addons/limboai/bin/
          echo "---"
          if [ "$RUNNER_OS" == "macOS" ]; then
            strip -u out/addons/limboai/bin/liblimboai*/liblimboai*
          else
            strip out/addons/limboai/bin/liblimboai*
          fi
          echo "---"
          ls -l -R out/addons/limboai/bin/

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        env:
          NAME: tmp-gdextension.${{matrix.opts.platform}}.${{matrix.opts.target}}.${{matrix.opts.arch}}
        with:
          name: ${{ env.NAME }}
          path: out/*

  merge-artifacts:
    name: Merge artifacts
    runs-on: ubuntu-latest
    needs: gdextension

    steps:
      - name: Merge artifacts
        uses: actions/upload-artifact/merge@v4
        with:
          name: ${{needs.gdextension.outputs.name-prefix}}
          pattern: tmp-gdextension.*
          delete-merged: true