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"
  GODOT_VERSION: 4.2-stable

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: ${{ !inputs.test-build }}

          - name: 🌐 Web (wasm32, debug)
            runner: ubuntu-20.04
            platform: web
            target: template_debug
            arch: wasm32
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (arm64, release)
            runner: ubuntu-20.04
            platform: android
            target: template_release
            arch: arm64
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (arm64, debug)
            runner: ubuntu-20.04
            platform: android
            target: template_debug
            arch: arm64
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (arm32, release)
            runner: ubuntu-20.04
            platform: android
            target: template_release
            arch: arm32
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (arm32, debug)
            runner: ubuntu-20.04
            platform: android
            target: template_debug
            arch: arm32
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (x86_64, release)
            runner: ubuntu-20.04
            platform: android
            target: template_release
            arch: x86_64
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (x86_64, debug)
            runner: ubuntu-20.04
            platform: android
            target: template_debug
            arch: x86_64
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (x86_32, release)
            runner: ubuntu-20.04
            platform: android
            target: template_release
            arch: x86_32
            should-build: ${{ !inputs.test-build }}

          - name: 🤖 Android (x86_32, debug)
            runner: ubuntu-20.04
            platform: android
            target: template_debug
            arch: x86_32
            should-build: ${{ !inputs.test-build }}

        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: Setup Linux toolchain
        if: matrix.opts.platform == 'linux'
        uses: ./limboai/.github/actions/setup-linux-toolchain
        with:
          arch: ${{matrix.opts.arch}}

      - 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 != 'linux'
        run: |
          python -c "import sys; print(sys.version)"
          python -m pip install scons==4.4.0
          python --version
          scons --version

      - name: Set up Java 17
        if: matrix.opts.platform == 'android'
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - uses: nttld/setup-ndk@v1
        if: matrix.opts.platform == 'android'
        id: setup-ndk
        with:
          ndk-version: r23c
          link-to-sdk: true

      - 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 "${LIMBOAI_VERSION}" > out/addons/limboai/version.txt
          echo "---"
          ls -R out/

      - 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/*

  package-extension:
    name: 📦 Package extension
    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

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: ${{needs.gdextension.outputs.name-prefix}}
          path: out/

      - name: Setup Godot
        shell: bash
        run: |
          echo "Downloading Godot ${GODOT_VERSION}"
          mkdir bin
          cd bin
          wget "https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
          unzip godot.zip
          rm godot.zip
          mv Godot_* godot
          chmod u+x godot
          ls -l
          cd ..
          ./bin/godot --version

      - name: Generate icon .import files
        shell: bash
        run: |
          touch out/project.godot
          timeout 20s ./bin/godot --headless --editor --path ./out/ || /bin/true
          rm out/project.godot
          rm -rf out/.godot/

      - name: Change editor icon import settings
        shell: bash
        run: |
          echo "--- Listing icons dir:"
          ls out/addons/limboai/icons/
          echo "--- (end of listing)"
          sed -i 's|editor/scale_with_editor_scale=false|editor/scale_with_editor_scale=true|' out/addons/limboai/icons/*.import
          sed -i 's|editor/convert_colors_with_editor_theme=false|editor/convert_colors_with_editor_theme=true|' out/addons/limboai/icons/*.import

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{needs.gdextension.outputs.name-prefix}}
          path: out/*
          overwrite: true
