name: Build CI

on:
  push:
    paths-ignore:
      - '**.md'
  pull_request:
    paths-ignore:
      - '**.md'

env:
  BUILD_CONFIG: Release
  QT_VERSION: '6.11.0'
  SCCACHE_GHA_ENABLED: "true"

jobs:
  desktop-build:
    name: Desktop (${{ matrix.platform }})
    runs-on: ${{ matrix.runs_on }}

    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            runs_on: ubuntu-latest
            platform: linux-x64
            arch: x86_64
            cmake_preset: ci-linux-clang-appimage
            linuxdeploy_command: /usr/local/bin/linuxdeploy-x86_64.AppImage
            cache_path: ''
            qt_install_deps: 'true'

          - os: ubuntu-24.04-arm
            runs_on: ubuntu-24.04-arm
            platform: linux-arm64
            arch: aarch64
            cmake_preset: ci-linux-clang-appimage
            linuxdeploy_command: /usr/local/bin/linuxdeploy-aarch64.AppImage
            cache_path: ''
            qt_install_deps: 'true'

          - os: windows-latest
            runs_on: windows-latest
            platform: windows-x64
            arch: x86_64
            cmake_preset: ci-windows-msvc
            vcpkg_root: C:\vcpkg
            vcpkg_triplet: x64-windows-static-md
            cache_path: |
              C:\vcpkg\installed
              C:\vcpkg\packages
            qt_install_deps: 'false'

          - os: windows-11-arm
            runs_on: windows-11-arm
            platform: windows-arm64
            cmake_preset: ci-windows-msys2-clang
            msys2_env: CLANGARM64
            cache_path: C:\msys2-ccache
            qt_install_deps: 'false'

          - os: macos-intel
            platform: macos-x64
            runs_on: macos-latest
            cmake_preset: ci-macos-x64
            cache_path: ~/Library/Caches/ccache
            qt_install_deps: 'false'

          - os: macos-arm64
            platform: macos-arm64
            runs_on: macos-latest
            cmake_preset: ci-macos-arm64
            cache_path: ~/Library/Caches/ccache
            qt_install_deps: 'false'

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
          submodules: recursive

      - name: Restore cache
        uses: actions/cache@v5
        if: ${{ matrix.cache_path != '' }}
        with:
          path: ${{ matrix.cache_path }}
          key: cache-${{ matrix.platform }}-${{ env.BUILD_CONFIG }}-${{ hashFiles('CMakeLists.txt', 'CMakePresets.json', 'cmake/**', '.ci/**', '.github/workflows/c-cpp.yml', 'vcpkg.json') }}
          restore-keys: |
            cache-${{ matrix.platform }}-${{ env.BUILD_CONFIG }}-

      - name: Set up build environment (Linux)
        run: bash ./.ci/setup-linux.sh ${{ matrix.arch }} with-appimage
        if: startsWith(matrix.platform, 'linux-')

      - name: Set up build environment (macOS)
        run: bash ./.ci/setup-macos.sh
        if: startsWith(matrix.platform, 'macos-')

      - name: Set up build environment (Windows MSVC)
        shell: pwsh
        env:
          VCPKG_ROOT: ${{ matrix.vcpkg_root }}
        run: .\.ci\setup-windows-msvc.ps1 -VcpkgTriplet '${{ matrix.vcpkg_triplet }}'
        if: matrix.platform == 'windows-x64'

      - uses: TheMrMilchmann/setup-msvc-dev@v4
        with:
          arch: ${{ matrix.arch }}
        if: matrix.platform == 'windows-x64'

      - uses: mozilla-actions/sccache-action@v0.0.10
        if: startsWith(matrix.platform, 'linux-') || matrix.platform == 'windows-x64'
        with:
          disable_annotations: true

      - name: Set up MSYS2 (Windows ARM)
        uses: msys2/setup-msys2@v2
        if: matrix.platform == 'windows-arm64'
        with:
          msystem: ${{ matrix.msys2_env }}
          update: true
          cache: true
          install: |
            git
          pacboy: |
            clang:p
            ccache:p
            cmake:p
            lld:p
            ninja:p
            boost:p
            openssl:p
            curl:p
            zlib:p
            qt6-base:p
            qt6-multimedia:p
            qt6-svg:p
            qt6-tools:p

      - name: Reset ccache statistics
        run: ccache -z
        if: startsWith(matrix.platform, 'macos-')

      - name: Install Qt 6.11.0 (Windows MSVC)
        uses: jurplel/install-qt-action@v4
        if: matrix.platform == 'windows-x64'
        with:
          version: ${{ env.QT_VERSION }}
          modules: qtmultimedia
          host: windows
          target: desktop
          arch: win64_msvc2022_64
          cache: true
          install-deps: ${{ matrix.qt_install_deps }}
          aqtsource: git+https://github.com/miurahr/aqtinstall.git@f383b3c7d9658e881bd8ce8810057393bd934ee1

      - name: Install Qt 6.11.0
        uses: jurplel/install-qt-action@v4
        if: matrix.platform != 'windows-arm64' && matrix.platform != 'windows-x64'
        with:
          version: ${{ env.QT_VERSION }}
          modules: qtmultimedia
          cache: true
          install-deps: ${{ matrix.qt_install_deps }}

      - name: Build desktop target (Linux/macOS)
        env:
          VITA3K_LINUXDEPLOY_COMMAND: ${{ matrix.linuxdeploy_command }}
        run: bash ./.ci/build-desktop.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
        if: startsWith(matrix.platform, 'linux-') || startsWith(matrix.platform, 'macos-')

      - name: Build desktop target (Windows MSVC)
        shell: bash
        env:
          VCPKG_ROOT: ${{ matrix.vcpkg_root }}
        run: bash ./.ci/build-desktop.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
        if: matrix.platform == 'windows-x64'

      - name: Build desktop target (Windows ARM MSYS2)
        shell: msys2 {0}
        run: bash ./.ci/build-windows-msys2.sh --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }}
        if: matrix.platform == 'windows-arm64'

      - name: Compute artifact paths
        shell: bash
        run: |
          echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
          echo "ARTIFACT_NAME=vita3k-$(git rev-parse --short HEAD)-${{ matrix.platform }}" >> "$GITHUB_ENV"
          echo "ARTIFACT_DIR=artifacts/vita3k-$(git rev-parse --short HEAD)-${{ matrix.platform }}" >> "$GITHUB_ENV"

      - name: Stage desktop artifact (Linux/macOS)
        run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
        if: startsWith(matrix.platform, 'linux-') || startsWith(matrix.platform, 'macos-')

      - name: Stage desktop artifact (Windows MSVC)
        shell: bash
        run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
        if: matrix.platform == 'windows-x64'

      - name: Stage desktop artifact (Windows ARM MSYS2)
        shell: msys2 {0}
        run: bash ./.ci/package-desktop.sh --platform ${{ matrix.platform }} --preset ${{ matrix.cmake_preset }} --config ${{ env.BUILD_CONFIG }} --output-dir "${{ env.ARTIFACT_DIR }}"
        if: matrix.platform == 'windows-arm64'

      - name: Print ccache statistics
        run: ccache -s
        if: startsWith(matrix.platform, 'macos-')

      - name: Print sccache statistics
        run: sccache --show-stats
        if: startsWith(matrix.platform, 'linux-') || matrix.platform == 'windows-x64'

      - name: Upload desktop artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ env.ARTIFACT_NAME }}
          path: ${{ env.ARTIFACT_DIR }}

  android-build:
    name: Android
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0
          submodules: recursive

      - name: Restore native dependency cache
        uses: actions/cache@v5
        with:
          path: |
            /usr/local/share/vcpkg/installed
            /usr/local/share/vcpkg/packages
          key: cache-android-native-${{ hashFiles('CMakeLists.txt', 'cmake/**', '.ci/**', 'android/app/build.gradle', 'vcpkg.json') }}
          restore-keys: |
            cache-android-native-

      - name: Set up Java
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: '17'

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v6
        with:
          add-job-summary: on-failure
          cache-provider: basic
          validate-wrappers: false

      - name: Set up Android SDK tools
        uses: android-actions/setup-android@v4

      - name: Set up Android build environment
        env:
          VCPKG_ROOT: /usr/local/share/vcpkg
        run: bash ./.ci/setup-android.sh

      - uses: hendrikmuhs/ccache-action@v1.2.23

      - name: Decode Android keystore
        env:
          KEYSTORE_ENCODED: ${{ secrets.KEYSTORE }}
        run: |
          if [ -n "$KEYSTORE_ENCODED" ]; then
            echo "$KEYSTORE_ENCODED" | base64 --decode > /home/runner/keystore.jks
          fi

      - name: Compute artifact paths
        shell: bash
        run: |
          echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
          echo "ARTIFACT_NAME=vita3k-$(git rev-parse --short HEAD)-android" >> "$GITHUB_ENV"
          echo "ARTIFACT_DIR=artifacts/vita3k-$(git rev-parse --short HEAD)-android" >> "$GITHUB_ENV"

      - name: Build Android target
        env:
          SIGNING_STORE_PATH: /home/runner/keystore.jks
          SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
          SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
          SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
          VCPKG_ROOT: /usr/local/share/vcpkg
          ANDROID_NDK_HOME: ${{ env.ANDROID_NDK_HOME }}
        run: bash ./.ci/build-android.sh "${{ env.ARTIFACT_DIR }}"

      - name: Print Android ccache statistics
        run: ccache -s

      - name: Upload Android artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ env.ARTIFACT_NAME }}
          path: ${{ env.ARTIFACT_DIR }}

  create-release:
    needs: [desktop-build, android-build]
    runs-on: ubuntu-latest
    concurrency:
      group: create-release
      cancel-in-progress: false
    if: |
      github.ref == 'refs/heads/master' &&
      github.repository == 'Vita3K/Vita3K'
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Download artifacts
        uses: actions/download-artifact@v8

      - name: Get commit info
        run: |
          echo "GIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"
          echo "BUILD_VARIABLE=$(git rev-list --count HEAD)" >> "$GITHUB_ENV"
          echo "LAST_COMMIT_MESSAGE=$(git log -1 --pretty=format:'%s')" >> "$GITHUB_ENV"

      - name: Get last committer
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          COMMITTER=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
          https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }} \
          | jq -r '.commit.author.name')
          echo "COMMITTER_NAME=$COMMITTER" >> "$GITHUB_ENV"

      - name: Prepare release artifacts
        run: bash ./.ci/release-collect.sh

      - name: Upload to store repository
        uses: tcnksm/ghr@v0
        with:
          tag: ${{ env.BUILD_VARIABLE }}
          path: artifacts-store/
          owner: ${{ github.repository_owner }}
          repository: Vita3K-builds
          name: "Build: ${{ env.BUILD_VARIABLE }}"
          body: "Corresponding commit: [${{ env.LAST_COMMIT_MESSAGE }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }}) (${{ env.COMMITTER_NAME }})"
          token: ${{ secrets.STORE_TOKEN }}

      - name: Upload to master repository
        uses: tcnksm/ghr@v0
        with:
          tag: continuous
          path: artifacts-master/
          delete: "true"
          owner: ${{ github.repository_owner }}
          repository: Vita3K
          name: "Automatic CI builds"
          body: "Corresponding commit: ${{ github.sha }}\nVita3K Build: ${{ env.BUILD_VARIABLE }}"
