name: Build Horizon OC Zeus

on:
  push:
    branches: [ develop, main, master ]
  pull_request:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    # Minimal devkitA64 container
    container:
      image: devkitpro/devkita64:20260219

    steps:
      - name: Checkout repository and submodules # needed for hoc-clk
        uses: actions/checkout@v6.0.2
        with:
          submodules: recursive


      # -------------------------------------------------
      # Fix PATH for devkitA64 and devkitARM
      # -------------------------------------------------
      - name: Set devkitPro PATH
        run: |
          echo "DEVKITPRO=/opt/devkitpro" >> $GITHUB_ENV
          echo "DEVKITA64=/opt/devkitpro/devkitA64" >> $GITHUB_ENV
          echo "DEVKITARM=/opt/devkitpro/devkitARM" >> $GITHUB_ENV
          echo "PATH=/opt/devkitpro/devkitA64/bin:/opt/devkitpro/devkitARM/bin:$PATH" >> $GITHUB_ENV
        shell: bash

      - name: Check devkitPro gcc and g++ versions
        run: |
          aarch64-none-elf-gcc --version
          aarch64-none-elf-g++ --version
        shell: bash # is this even needed? but for consistency let's keep using it

      - name: Install ccache
        run: |
          apt-get update
          apt-get install -y ccache
        shell: bash

      # -------------------------------------------------
      # Get short commit SHA
      # -------------------------------------------------
      - name: Set commit SHA & dist
        id: vars
        run: |
          echo "SHORT_SHA=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV
          echo $SHORT_SHA > dist/.commit
          echo $GITHUB_SHA >> dist/.commit

      - name: Clone Libnx
        run: git clone https://github.com/switchbrew/libnx.git --depth=1 --single-branch -b v4.12.0

      - name: Clone Atmosphere
        run: git clone --depth=1 --single-branch https://github.com/Atmosphere-NX/Atmosphere.git atmosphere -b $(cat ams_ver.txt)

      - name: Prepare build folder
        run: |
          mkdir -p build
          cp -r atmosphere/* build/

      - name: Override ldr_process_creation.cpp
        run: |
          cp -rf Source/Atmosphere/stratosphere/loader/source/* build/stratosphere/loader/source/

      - name: Cache ccache
        uses: actions/cache@v5.0.5
        with:
          path: .ccache
          key: ccache-${{ runner.os }}-devkitpro-ams-${{ hashFiles('ams_ver.txt') }}
          restore-keys: |
            ccache-${{ runner.os }}-devkitpro-

      - name: Configure ccache
        run: |
          export CCACHE_DIR="$GITHUB_WORKSPACE/.ccache"
          export CCACHE_COMPILERCHECK=content
          export CCACHE_NOHASHDIR=true
          echo "CCACHE_DIR=$GITHUB_WORKSPACE/.ccache" >> $GITHUB_ENV
          echo "CCACHE_BASEDIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV
          echo "CCACHE_COMPILERCHECK=content" >> $GITHUB_ENV
          echo "CCACHE_NOHASHDIR=true" >> $GITHUB_ENV
          ccache --set-config=max_size=10G
          ccache --set-config=compiler_check=content
          ccache --set-config=hash_dir=false
          ccache -s
          ls -lah "$GITHUB_WORKSPACE/.ccache"

      - name: Build Libnx
        shell: bash
        run: |
          export CC="ccache aarch64-none-elf-gcc"
          export CXX="ccache aarch64-none-elf-g++"
          pushd libnx
          make -j$(($(nproc) * 4)) install CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
          popd

      - name: Build hoc-clk sysmodule and overlay
        shell: bash
        run: |
          export CC="ccache aarch64-none-elf-gcc"
          export CXX="ccache aarch64-none-elf-g++"

          ROOT_DIR="$GITHUB_WORKSPACE/Source/hoc-clk"
          DIST_DIR="$ROOT_DIR/dist"
          echo "DIST_DIR="$ROOT_DIR/dist"" >> $GITHUB_ENV
          
          mkdir -p "$DIST_DIR"

          echo "*** sysmodule ***"

          TITLE_ID="$(grep -oP '"title_id":\s*"0x\K(\w+)' \
            "$ROOT_DIR/sysmodule/perms.json")"

          echo "TITLE_ID: $TITLE_ID"

          pushd "$ROOT_DIR/sysmodule"
          git config --global --add safe.directory "$GITHUB_WORKSPACE"
          make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
          popd

          mkdir -p "$DIST_DIR/atmosphere/contents/$TITLE_ID/flags"

          cp -vf \
            "$ROOT_DIR/sysmodule/out/hoc-clk.nsp" \
            "$DIST_DIR/atmosphere/contents/$TITLE_ID/exefs.nsp"

          : >"$DIST_DIR/atmosphere/contents/$TITLE_ID/flags/boot2.flag"

          cp -vf \
            "$ROOT_DIR/sysmodule/toolbox.json" \
            "$DIST_DIR/atmosphere/contents/$TITLE_ID/toolbox.json"

          echo "*** overlay ***"

          pushd "$ROOT_DIR/overlay"
          make -j$(($(nproc) * 2)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
          popd

          mkdir -p "$DIST_DIR/switch/.overlays"

          cp -vf \
            "$ROOT_DIR/overlay/out/horizon-oc-overlay.ovl" \
            "$DIST_DIR/switch/.overlays/horizon-oc-overlay.ovl"

          echo "*** assets ***"

          mkdir -p "$DIST_DIR/config/horizon-oc"

          cp -vf \
            "$ROOT_DIR/config.ini.template" \
            "$DIST_DIR/config/horizon-oc/config.ini.template"

          cp -vf \
            "$ROOT_DIR/README.md" \
            "$DIST_DIR/README.md"

      - name: Build kip
        working-directory: build/stratosphere/loader
        run: |
          export CC="ccache aarch64-none-elf-gcc"
          export CXX="ccache aarch64-none-elf-g++"
          make -j$(($(nproc) * 4)) CXX="ccache aarch64-none-elf-g++" CC="ccache aarch64-none-elf-gcc"
          hactool -t kip1 out/nintendo_nx_arm64_armv8a/release/loader.kip --uncompress=hoc.kip
          cp hoc.kip ../../../dist/atmosphere/kips/hoc.kip
          
      - name: ccache stat
        run: |
             ccache --show-stats
             ccache -s
             ccache --show-config

      # -------------------------------------------------
      # Upload ZIP artifact
      # -------------------------------------------------
      - name: Upload build artifact
        uses: actions/upload-artifact@v6
        with:
          name: horizon-oc-zeus-dist
          path: $DIST_DIR
          compression-level: 6
