name: iOS

on:
  push:
    branches:
      - master
    paths: &ios_paths
      - '.github/workflows/ios.yml'
      - 'app/ios/**'
      - 'app/android/jni/**'
      - 'corelib/**'
      - 'utilite/**'
      - 'cmake_modules/**'
      - 'CMakeLists.txt'
  pull_request:
    branches:
      - '**'
    paths: *ios_paths

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
  # Pre-built iOS dependencies (content of app/ios/RTABMapApp/Libraries, generated by install_deps.sh).
  # Bump this when the dependency set changes (must match the Xcode toolchain below).
  DEPS_URL: https://github.com/introlab/rtabmap/releases/download/0.23.1/libraries-ios-xcode26.5.zip
  XCODE_VERSION: '26.5'

jobs:
  build:
    name: build-ios
    # macos-26 (Tahoe) ships Xcode 26.x, matching the toolchain used to build the prebuilt libraries.
    runs-on: macos-26

    steps:
      - uses: actions/checkout@v4

      - name: Select Xcode ${{ env.XCODE_VERSION }}
        uses: maxim-lobanov/setup-xcode@v1
        with:
          xcode-version: ${{ env.XCODE_VERSION }}

      - name: Versions
        run: |
          xcodebuild -version
          cmake --version || brew install cmake

      - name: Cache prebuilt dependencies archive
        id: deps-cache
        uses: actions/cache@v4
        with:
          path: deps.zip
          # Keyed on the archive URL (release tag + filename), so the cache is
          # reused until DEPS_URL is bumped, regardless of other workflow edits.
          key: ${{ runner.os }}-ios-deps-${{ env.DEPS_URL }}

      - name: Download prebuilt dependencies
        if: steps.deps-cache.outputs.cache-hit != 'true'
        run: curl -L "$DEPS_URL" -o deps.zip

      - name: Extract dependencies into Libraries
        run: |
          set -eux
          mkdir -p app/ios/RTABMapApp/Libraries
          rm -rf deps_extract && mkdir -p deps_extract
          unzip -q deps.zip -d deps_extract
          # The archive holds the *content* of the Libraries folder (include/ lib/ share/),
          # but tolerate an extra top-level Libraries/ wrapper just in case.
          if [ -d deps_extract/Libraries ]; then
            SRC=deps_extract/Libraries
          else
            SRC=deps_extract
          fi
          cp -R "$SRC"/. app/ios/RTABMapApp/Libraries/
          test -d app/ios/RTABMapApp/Libraries/include
          test -d app/ios/RTABMapApp/Libraries/lib

      - name: Build rtabmap core (third-party deps are skipped, already provided by the archive)
        working-directory: app/ios/RTABMapApp
        run: ./install_deps.sh

      - name: Build RTABMapApp
        run: |
          xcodebuild \
            -project app/ios/RTABMapApp.xcodeproj \
            -scheme RTABMapApp \
            -configuration Release \
            -sdk iphoneos \
            -destination 'generic/platform=iOS' \
            -derivedDataPath build \
            CODE_SIGNING_ALLOWED=NO \
            CODE_SIGNING_REQUIRED=NO \
            CODE_SIGN_IDENTITY="" \
            DEVELOPMENT_TEAM="" \
            build

      - name: Package app (unsigned .ipa)
        run: |
          set -eux
          APP_DIR="build/Build/Products/Release-iphoneos"
          rm -rf Payload && mkdir Payload
          cp -R "$APP_DIR/RTABMapApp.app" Payload/
          # Unsigned .ipa: not installable as-is, but ready for later (re)signing.
          zip -q -r RTABMapApp-unsigned.ipa Payload

      - name: Upload app artifact
        uses: actions/upload-artifact@v4
        with:
          name: RTABMapApp-ios-unsigned
          path: RTABMapApp-unsigned.ipa
          compression-level: 0
          if-no-files-found: error
          retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }}
