name: 🍎 macOS builds
on:
  workflow_call:
    inputs:
      godot-treeish:
        description: A tag, branch or commit hash in the Godot repository.
        type: string
        default: master
      limboai-treeish:
        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-treeish:
        description: A tag, branch or commit hash in the Godot repository.
        type: string
        default: master
      limboai-treeish:
        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 werror=yes
  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
            build-mono: false
            artifact-name: macos-editor
            should-build: true

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

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

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

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

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

          # ! Disabled for now: .NET version fails to build

          # - name: .NET Editor (x86_64, release)
          #   target: editor
          #   arch: x86_64
          #   build-mono: true
          #   artifact-name: macos-mono-editor
          #   cache-name: macos-editor
          #   should-build: ${{ !inputs.test-build }}

          # - name: .NET Template (x86_64, release)
          #   target: template_release
          #   arch: x86_64
          #   build-mono: true
          #   artifact-name: macos-mono-templates
          #   should-build: ${{ !inputs.test-build }}

          # - name: .NET Template (x86_64, debug)
          #   target: template_debug
          #   arch: x86_64
          #   build-mono: true
          #   artifact-name: macos-mono-templates
          #   should-build: ${{ !inputs.test-build }}

          # - name: .NET Editor (arm64, release)
          #   target: editor
          #   arch: arm64
          #   build-mono: true
          #   artifact-name: macos-mono-editor
          #   cache-name: macos-editor
          #   should-build: ${{ !inputs.test-build }}

          # - name: .NET Template (arm64, release)
          #   target: template_release
          #   arch: arm64
          #   build-mono: true
          #   artifact-name: macos-mono-templates
          #   should-build: ${{ !inputs.test-build }}

          # - name: .NET Template (arm64, debug)
          #   target: template_debug
          #   arch: arm64
          #   build-mono: true
          #   artifact-name: macos-mono-templates
          #   should-build: ${{ !inputs.test-build }}

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

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

    steps:

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

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

      # 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@v4
        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: 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@v3
        with:
          path: ${{github.workspace}}/.scons_cache/
          key: ${{env.BIN}}-${{inputs.godot-treeish}}-${{inputs.limboai-treeish}}-${{env.LIMBOAI_VERSION}}
          restore-keys: |
            ${{env.BIN}}-${{inputs.godot-treeish}}-${{inputs.limboai-treeish}}-${{env.LIMBOAI_VERSION}}
            ${{env.BIN}}-${{inputs.godot-treeish}}-${{inputs.limboai-treeish}}
            ${{env.BIN}}-${{inputs.godot-treeish}}

      - 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.build-mono}} ${{env.SCONSFLAGS}}

      # ! Disabled for now: .NET version fail to build

      # - name: Generate C# glue
      #   if: matrix.opts.build-mono && matrix.opts.target == 'editor'
      #   run: |
      #     ./bin/$BIN --headless --generate-mono-glue ./modules/mono/glue || true

      # - name: Build .NET solutions
      #   if: matrix.opts.build-mono && matrix.opts.target == 'editor'
      #   run: |
      #     ./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=macos

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

      - name: Upload artifact
        uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.opts.artifact-name }}
          path: bin/*

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

    steps:

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

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

      # 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@v3
        with:
          name: macos-editor
          path: bin/

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

      - name: Upload editor bundle
        uses: actions/upload-artifact@v3
        with:
          name: ${{env.NAME_PREFIX}}.editor.macos.universal
          path: out/editor/*

      - name: Download templates artifact
        if: ${{ !inputs.test-build }}
        uses: actions/download-artifact@v3
        with:
          name: macos-templates
          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
          rm bin/godot.macos.template_{debug,release}.{x86_64,arm64}
          strip bin/godot.*
          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 -r macos.zip macos_template.app
          rm bin/*
          mkdir -p out/templates/
          mv macos.zip out/templates/macos.zip
          echo "${GODOT_VERSION}.limboai+${LIMBOAI_VERSION}" > out/templates/version.txt
          ls out/templates/

      - uses: geekyeggo/delete-artifact@v2
        with:
            name: macos-*
            useGlob: true
            failOnError: false

      - name: Upload templates bundle
        if: ${{ !inputs.test-build }}
        uses: actions/upload-artifact@v3
        with:
          name: ${{env.NAME_PREFIX}}.export-templates
          path: out/*