name: Circuits Build
on:
  pull_request:
    branches:
      - dev
      - staging
      - main
    paths:
      - "circuits/circuits/**"
      - ".github/workflows/artifacts.yml"
  workflow_dispatch:
    inputs:
      circuit-type:
        description: "Circuits to build (comma-separated: register, register_id, register_aadhaar, disclose, dsc). Leave empty to build all."
        required: false
        type: string
        default: ""
      circuit-name:
        description: "Circuit names to build (comma-separated: register_sha256_sha224_sha224_ecdsa_secp224r1, dsc_sha256_rsa_65537_4096). Cannot be used with circuit-type."
        required: false
        type: string
        default: ""
      run-id:
        description: "Run ID to download artifacts ."
        required: false
        type: string
        default: ""

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

jobs:
  build:
    runs-on: ["128ram"]
    permissions:
      contents: read
      actions: read
    env:
      CIRCOM_VERSION: "2.1.9"
      CIRCOM_SHA256: "e5575829252d763b7818049df9de2ef9304df834697de77fa63ce7babc23c967"

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

      - name: Install cpp dependencies
        run: |
          sudo apt-get update
          sudo apt-get install --yes \
            build-essential \
            libgmp-dev \
            libsodium-dev \
            nasm \
            nlohmann-json3-dev \
            wget

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

      - name: Restore Circom binary
        id: circom-cache
        uses: actions/cache/restore@v4
        with:
          path: ~/.cache/circom
          key: circom-v2.1.9

      - name: Download Circom Binary v2.1.9
        if: steps.circom-cache.outputs.cache-hit != 'true'
        run: |
          mkdir -p ~/.cache/circom

          # Download with curl (more reliable than wget in CI environments)
          # Use exponential backoff retry logic
          for attempt in 1 2 3; do
            echo "Download attempt $attempt/3..."

            if curl -L --connect-timeout 30 --max-time 300 \
                --retry 3 --retry-delay 2 --retry-max-time 600 \
                -o ~/.cache/circom/circom \
                "https://github.com/iden3/circom/releases/download/v${{ env.CIRCOM_VERSION }}/circom-linux-amd64"; then
              echo "✅ Download successful!"
              break
            else
              echo "❌ Download failed on attempt $attempt"
              if [ $attempt -eq 3 ]; then
                echo "💥 All download attempts failed"
                exit 1
              fi
              # Exponential backoff: 5s, 10s, 20s
              sleep_time=$((5 * attempt))
              echo "⏳ Waiting ${sleep_time}s before retry..."
              sleep $sleep_time
            fi
          done

          # Verify file exists and has content
          if [ ! -f ~/.cache/circom/circom ]; then
            echo "💥 Error: circom binary file is missing"
            exit 1
          fi

          if [ ! -s ~/.cache/circom/circom ]; then
            echo "💥 Error: circom binary file is empty"
            exit 1
          fi

          echo "📁 File size: $(ls -lh ~/.cache/circom/circom | awk '{print $5}')"
          chmod +x ~/.cache/circom/circom

          # Verify checksum
          echo "🔍 Verifying checksum..."
          echo "${{ env.CIRCOM_SHA256 }}  $HOME/.cache/circom/circom" | sha256sum -c -

      - name: Save Circom cache
        if: steps.circom-cache.outputs.cache-hit != 'true'
        uses: actions/cache/save@v4
        with:
          path: ~/.cache/circom
          key: circom-v2.1.9

      - name: Verify Circom checksum (cache hit)
        if: steps.circom-cache.outputs.cache-hit == 'true'
        run: |
          echo "${{ env.CIRCOM_SHA256 }}  $HOME/.cache/circom/circom" | sha256sum -c -

      - name: Add Circom to PATH
        run: echo "$HOME/.cache/circom" >> "$GITHUB_PATH"

      - name: Read and sanitize Node.js version
        shell: bash
        run: |
          if [ ! -f .nvmrc ] || [ -z "$(cat .nvmrc)" ]; then
            echo "❌ .nvmrc is missing or empty"; exit 1;
          fi
          VERSION="$(tr -d '\r\n' < .nvmrc)"
          VERSION="${VERSION#v}"
          if ! [[ "$VERSION" =~ ^[0-9]+(\.[0-9]+){0,2}$ ]]; then
            echo "Invalid .nvmrc content: '$VERSION'"; exit 1;
          fi
          echo "NODE_VERSION=$VERSION" >> "$GITHUB_ENV"
          echo "NODE_VERSION_SANITIZED=${VERSION//\//-}" >> "$GITHUB_ENV"
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Install Yarn
        run: npm i -g yarn

      - name: Install dependencies
        uses: ./.github/actions/yarn-install
        with:
          working_directory: circuits

      - name: Print Circom version
        run: circom --version

      - name: Download previous artifacts
        if: github.event_name == 'workflow_dispatch' && inputs.run-id != ''
        uses: dawidd6/action-download-artifact@v6
        with:
          name: circuits
          path: output/
          run_id: ${{ inputs.run-id }}

      - name: Build cpp circuits
        run: |
          chmod +x circuits/scripts/build/build_cpp.sh
          chmod +x circuits/scripts/build/build_single_circuit.sh

          # Validate inputs - only one should be provided
          if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
            if [[ "${{ inputs.circuit-type }}" != "" && "${{ inputs.circuit-name }}" != "" ]]; then
              echo " Error: Cannot provide both circuit-type and circuit-name. Use only one."
              exit 1
            fi
          fi

          # Check what type of build to perform
          if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.circuit-name }}" != "" ]]; then
            # Build circuits by name
            INPUT_CIRCUITS="${{ inputs.circuit-name }}"
            INPUT_CIRCUITS=$(echo "$INPUT_CIRCUITS" | tr -d ' ')
            IFS=',' read -ra CIRCUITS_ARRAY <<< "$INPUT_CIRCUITS"

            echo "Building selected circuits: ${{ inputs.circuit-name }}"
            for circuit_name in "${CIRCUITS_ARRAY[@]}"; do
              echo "Building circuit: $circuit_name"
              ./circuits/scripts/build/build_single_circuit.sh "$circuit_name"
            done

          elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.circuit-type }}" != "" ]]; then
            # Build circuits by type
            INPUT_CIRCUITS="${{ inputs.circuit-type }}"
            INPUT_CIRCUITS=$(echo "$INPUT_CIRCUITS" | tr -d ' ')
            IFS=',' read -ra CIRCUITS_ARRAY <<< "$INPUT_CIRCUITS"

            echo "Building selected circuits: ${{ inputs.circuit-type }}"
            for circuit in "${CIRCUITS_ARRAY[@]}"; do
              echo "Building circuit: $circuit"
              ./circuits/scripts/build/build_cpp.sh "$circuit"
            done

          else
            # Build all circuits (default behavior)
            echo "Building all circuits (default behavior)"
            ./circuits/scripts/build/build_cpp.sh register
            ./circuits/scripts/build/build_cpp.sh register_id
            ./circuits/scripts/build/build_cpp.sh register_aadhaar
            ./circuits/scripts/build/build_cpp.sh disclose
            ./circuits/scripts/build/build_cpp.sh dsc
          fi

      - name: Upload Artifact
        uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4
        with:
          name: circuits
          path: output/
