name: Bindings tests

on:
  workflow_dispatch:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    types:
      - opened
      - reopened
      - synchronize
      - ready_for_review

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  xtask:
    uses: ./.github/workflows/xtask.yml

  test-uniffi-codegen:
    name: Test UniFFI bindings generation
    needs: xtask
    if: github.event_name == 'push' || !github.event.pull_request.draft
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Install protoc
        uses: taiki-e/install-action@v2
        with:
          tool: protoc@3.20.3

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      # Cargo config can screw with caching and is only used for alias config
      # and extra lints, which we don't care about here
      - name: Delete cargo config
        run: rm .cargo/config.toml

      - name: Load cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: ${{ github.ref == 'refs/heads/main' }}

      - name: Get xtask
        uses: actions/cache/restore@v4
        with:
          path: target/debug/xtask
          key: "${{ needs.xtask.outputs.cachekey-linux }}"
          fail-on-cache-miss: true

      - name: Build library & generate bindings
        run: target/debug/xtask ci bindings

  test-android:
    name: matrix-rust-components-kotlin
    needs: xtask
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || !github.event.pull_request.draft

    steps:
      - name: Checkout Rust SDK
        uses: actions/checkout@v6

      - name: Checkout Kotlin Rust Components project
        uses: actions/checkout@v6
        with:
          repository: matrix-org/matrix-rust-components-kotlin
          path: rust-components-kotlin
          ref: main

      - name: Use JDK 17
        uses: actions/setup-java@v5
        with:
          distribution: 'temurin' # See 'Supported distributions' for available options
          java-version: '17'

      - name: Install android sdk
        uses: malinskiy/action-android/install-sdk@release/0.1.7

      - name: Install android ndk
        uses: nttld/setup-ndk@v1
        id: install-ndk
        with:
          ndk-version: r27

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      # Cargo config can screw with caching and is only used for alias config
      # and extra lints, which we don't care about here
      - name: Delete cargo config
        run: rm .cargo/config.toml

      - name: Load cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: ${{ github.ref == 'refs/heads/main' }}

      - name: Get xtask
        uses: actions/cache/restore@v4
        with:
          path: target/debug/xtask
          key: "${{ needs.xtask.outputs.cachekey-linux }}"
          fail-on-cache-miss: true

      - name: Install Rust dependencies
        run: |
          rustup target add x86_64-linux-android
          cargo install cargo-ndk

      - name: Build SDK bindings for Android
        # Building for x86_64-linux-android as it's the most prone to breaking and building for every arch is too much
        run: |
          echo "Building SDK for x86_64-linux-android and creating bindings"
          target/debug/xtask kotlin build-android-library --package full-sdk --only-target x86_64-linux-android --src-dir rust-components-kotlin/sdk/sdk-android/src/main
          echo "Copying the result binary to the Android project"
          cd rust-components-kotlin
          echo "Building the Kotlin bindings"
          ./gradlew :sdk:sdk-android:assembleDebug

  test-apple:
    name: matrix-rust-components-swift
    needs: xtask
    runs-on: macos-15
    if: github.event_name == 'push' || !github.event.pull_request.draft

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      # install protoc in case we end up rebuilding opentelemetry-proto
      - name: Install protoc
        uses: taiki-e/install-action@v2
        with:
          tool: protoc@3.20.3

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Install aarch64-apple-ios target
        run: rustup target install aarch64-apple-ios

      # Cargo config can screw with caching and is only used for alias config
      # and extra lints, which we don't care about here
      - name: Delete cargo config
        run: rm .cargo/config.toml

      - name: Load cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: ${{ github.ref == 'refs/heads/main' }}

      - name: Get xtask
        uses: actions/cache/restore@v4
        with:
          path: target/debug/xtask
          key: "${{ needs.xtask.outputs.cachekey-macos }}"
          fail-on-cache-miss: true

      - name: Build library & bindings
        run: target/debug/xtask swift build-library

      - name: Run XCTests
        working-directory: bindings/apple
        run: swift test

      - name: Build Framework
        run: target/debug/xtask swift build-framework --target=aarch64-apple-ios --profile=dev --ios-deployment-target=18.0

  complement-crypto:
    name: "Run Complement Crypto tests"
    uses: matrix-org/complement-crypto/.github/workflows/single_sdk_tests.yml@main
    with:
        use_rust_sdk: "." # use local checkout
        use_complement_crypto: "MATCHING_BRANCH"

  test-crypto-apple-framework-generation:
    name: Generate Crypto FFI Apple XCFramework
    runs-on: macos-15
    if: github.event_name == 'push' || !github.event.pull_request.draft

    steps:
      - name: Checkout
        uses: actions/checkout@v6

      # install protoc in case we end up rebuilding opentelemetry-proto
      - name: Install protoc
        uses: taiki-e/install-action@v2
        with:
          tool: protoc@3.20.3

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Add rust targets
        run: |
          rustup target add aarch64-apple-ios

      # Cargo config can screw with caching and is only used for alias config
      # and extra lints, which we don't care about here
      - name: Delete cargo config
        run: rm .cargo/config.toml

      - name: Load cache
        uses: Swatinem/rust-cache@v2
        with:
          save-if: ${{ github.ref == 'refs/heads/main' }}

      - name: Run the Build Framework script
        run: ./bindings/apple/build_crypto_xcframework.sh -i

      - name: Is XCFramework generated?
        if: ${{ hashFiles('generated/MatrixSDKCryptoFFI.zip') != '' }}
        run: echo "XCFramework exists"
