name: 🍎 macOS builds
on:
  workflow_call:
    inputs:
      godot-ref:
        description: A tag, branch or commit hash in the Godot repository.
        type: string
        default: master
      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-ref:
        description: A tag, branch or commit hash in the Godot repository.
        type: string
        default: master
      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: production=yes tests=no verbose=yes warnings=extra
  DOTNET_NOLOGO: true
  DOTNET_CLI_TELEMETRY_OPTOUT: true

jobs:
  macos-builds:
    runs-on: "macos-latest"
    name: ${{ matrix.opts.name }}

    strategy:
      fail-fast: false
      matrix:
        opts:
          - name: Editor (x86_64, release)
            target: editor
            arch: x86_64
            dotnet: false
            should-build: true

          - name: Template (x86_64, release)
            target: template_release
            arch: x86_64
            dotnet: false
            should-build: ${{ !inputs.test-build }}

          - name: Template (x86_64, debug)
            target: template_debug
            arch: x86_64
            dotnet: false
            should-build: ${{ !inputs.test-build }}

          - name: Editor (arm64, release)
            target: editor
            arch: arm64
            dotnet: false
            should-build: true

          - name: Template (arm64, release)
            target: template_release
            arch: arm64
            dotnet: false
            should-build: ${{ !inputs.test-build }}

          - name: Template (arm64, debug)
            target: template_debug
            arch: arm64
            dotnet: false
            should-build: ${{ !inputs.test-build }}

          - name: .NET Editor (x86_64, release)
            target: editor
            arch: x86_64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

          - name: .NET Template (x86_64, release)
            target: template_release
            arch: x86_64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

          - name: .NET Template (x86_64, debug)
            target: template_debug
            arch: x86_64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

          - name: .NET Editor (arm64, release)
            target: editor
            arch: arm64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

          - name: .NET Template (arm64, release)
            target: template_release
            arch: arm64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

          - name: .NET Template (arm64, debug)
            target: template_debug
            arch: arm64
            dotnet: true
            should-build: ${{ !inputs.test-build }}

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

    env:
      BIN: godot.macos.${{matrix.opts.target}}.${{matrix.opts.arch}}${{  matrix.opts.dotnet == true && '.mono' || ''  }}

    steps:
      - name: Clone Godot
        uses: actions/checkout@v4
        with:
          repository: godotengine/godot
          ref: ${{ inputs.godot-ref }}

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

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

      - name: Set up Python 3.x
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"
          architecture: "x64"

      - name: Set up scons
        run: |
          python -c "import sys; print(sys.version)"
          python -m pip install scons==4.4.0

      - name: Set up .NET SDK 6.0
        if: matrix.opts.dotnet
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "6.0.x"

      - name: Diagnostics
        run: |
          python --version
          scons --version
          dotnet --info

      - name: Set up Vulkan SDK
        run: |
          sh misc/scripts/install_vulkan_sdk_macos.sh

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

      - name: Compilation
        env:
          SCONS_CACHE: ${{github.workspace}}/.scons_cache/
        run: |
          scons -j2 platform=macos target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} module_mono_enabled=${{matrix.opts.dotnet}} ${{env.SCONSFLAGS}}

      - name: Build .NET assemblies
        if: matrix.opts.dotnet && matrix.opts.target == 'editor'
        uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
        with:
          platform: macos

      - name: Prepare artifact
        run: |
          chmod +x bin/godot.*

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: tmp-${{matrix.opts.dotnet == true && 'dotnet-' || ''}}macos-${{matrix.opts.target}}-${{matrix.opts.arch}}
          path: bin/*

  make-macos-bundle:
    runs-on: "macos-latest"
    name: Make macOS Bundles
    needs: macos-builds

    strategy:
      fail-fast: false
      matrix:
        opts:
          - download-prefix: tmp-macos
            dotnet: false
            should-build: true
          - download-prefix: tmp-dotnet-macos
            dotnet: true
            should-build: ${{ !inputs.test-build }}
        exclude:
          - { opts: { should-build: false } }

    steps:
      - name: Clone Godot
        uses: actions/checkout@v4
        with:
          repository: godotengine/godot
          ref: ${{ inputs.godot-ref }}

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

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

      - name: Download editor artifact
        uses: actions/download-artifact@v4
        with:
          pattern: ${{matrix.opts.download-prefix}}-editor-*
          merge-multiple: true
          path: bin/

      # Zipping the editor bundle to retain executable bit;
      # workaround for: https://github.com/actions/upload-artifact/issues/38
      - name: Make editor bundle
        env:
          APP_NAME: Godot${{matrix.opts.dotnet == true && '_mono' || ''}}.app
        run: |
          ls bin/
          lipo -create bin/godot.macos.editor.x86_64* bin/godot.macos.editor.arm64* -output bin/godot.macos.editor.universal
          mkdir -p out/editor/
          cp -r misc/dist/macos_tools.app out/editor/${APP_NAME}
          mkdir -p out/editor/${APP_NAME}/Contents/{MacOS,Resources}
          cp bin/godot.macos.editor.universal out/editor/${APP_NAME}/Contents/MacOS/Godot
          chmod +x out/editor/${APP_NAME}/Contents/MacOS/Godot
          cp -r bin/GodotSharp out/editor/${APP_NAME}/Contents/Resources/GodotSharp || true
          pushd out/editor
          zip -q -9 -r ${APP_NAME}.zip ${APP_NAME}
          rm -rf ${APP_NAME}
          echo -e "## Why another ZIP inside?\n\nWorkaround for: https://github.com/actions/upload-artifact/issues/38\n" > README.md
          popd
          rm -rf bin/*
          ls out/editor/

      - name: Upload editor bundle
        uses: actions/upload-artifact@v4
        with:
          name: ${{env.NAME_PREFIX}}${{matrix.opts.dotnet == true && '.dotnet' || ''}}.editor.macos.universal
          path: out/editor/*

      - name: Download templates artifact
        if: ${{ !inputs.test-build }}
        uses: actions/download-artifact@v4
        with:
          pattern: ${{matrix.opts.download-prefix}}-template_*
          merge-multiple: true
          path: bin/

      - name: Make templates bundle
        if: ${{ !inputs.test-build }}
        run: |
          rm -rf out/
          ls bin/
          lipo -create bin/godot.macos.template_release.x86_64* bin/godot.macos.template_release.arm64* -output bin/godot.macos.template_release.universal
          lipo -create bin/godot.macos.template_debug.x86_64* bin/godot.macos.template_debug.arm64* -output bin/godot.macos.template_debug.universal
          cp -r misc/dist/macos_template.app macos_template.app
          mkdir -p macos_template.app/Contents/MacOS
          cp bin/godot.macos.template_debug.universal macos_template.app/Contents/MacOS/godot_macos_debug.universal
          cp bin/godot.macos.template_release.universal macos_template.app/Contents/MacOS/godot_macos_release.universal
          chmod +x macos_template.app/Contents/MacOS/godot_macos_{release,debug}.universal
          zip -q -9 -r macos.zip macos_template.app
          mkdir -p out/templates/
          mv macos.zip out/templates/macos.zip
          echo "${GODOT_VERSION}.limboai+${LIMBOAI_VERSION}${{matrix.opts.dotnet == true && '.mono' || ''}}" > out/templates/version.txt
          rm -rf bin/*
          ls out/templates/

      - uses: geekyeggo/delete-artifact@v5
        with:
          name: ${{matrix.opts.download-prefix}}-*
          useGlob: true
          failOnError: false

      - name: Upload templates bundle
        if: ${{ !inputs.test-build }}
        uses: actions/upload-artifact@v4
        with:
          name: ${{env.NAME_PREFIX}}${{matrix.opts.dotnet == true && '.dotnet' || ''}}.export-templates.macos
          path: out/*
