# Copyright 2024 RustFS Team
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Performance Testing

on:
  push:
    branches: [ main ]
    paths:
      - "**/*.rs"
      - "**/Cargo.toml"
      - "**/Cargo.lock"
      - ".github/workflows/performance.yml"
  workflow_dispatch:
    inputs:
      profile_duration:
        description: "Profiling duration in seconds"
        required: false
        default: "120"
        type: string

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  performance-profile:
    name: Performance Profiling
    runs-on: ubicloud-standard-2
    timeout-minutes: 30
    env:
      FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Setup Rust environment
        uses: ./.github/actions/setup
        with:
          rust-version: nightly
          cache-shared-key: perf-${{ hashFiles('**/Cargo.lock') }}
          cache-save-if: ${{ github.ref == 'refs/heads/main' }}
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Install additional nightly components
        run: rustup component add llvm-tools-preview

      - name: Install samply profiler
        uses: taiki-e/cache-cargo-install-action@v2
        with:
          tool: samply

      - name: Configure kernel for profiling
        run: echo '1' | sudo tee /proc/sys/kernel/perf_event_paranoid

      - name: Prepare test environment
        run: |
          # Create test volumes
          for i in {0..4}; do
            mkdir -p ./target/volume/test$i
          done

          # Set environment variables
          echo "RUSTFS_VOLUMES=./target/volume/test{0...4}" >> $GITHUB_ENV
          echo "RUST_LOG=rustfs=info,ecstore=info,s3s=info,iam=info,rustfs-obs=info" >> $GITHUB_ENV

      - name: Verify console static assets
        run: |
          # Console static assets are already embedded in the repository
          echo "Console static assets size: $(du -sh rustfs/static/)"
          echo "Console static assets are embedded via rust-embed, no external download needed"

      - name: Build with profiling optimizations
        run: |
          RUSTFLAGS="-C force-frame-pointers=yes -C debug-assertions=off" \
          cargo +nightly build --profile profiling -p rustfs --bins

      - name: Run performance profiling
        id: profiling
        run: |
          DURATION="${{ github.event.inputs.profile_duration || '120' }}"
          echo "Running profiling for ${DURATION} seconds..."

          timeout "${DURATION}s" samply record \
            --output samply-profile.json \
            ./target/profiling/rustfs ${RUSTFS_VOLUMES} || true

          if [ -f "samply-profile.json" ]; then
            echo "profile_generated=true" >> $GITHUB_OUTPUT
            echo "Profile generated successfully"
          else
            echo "profile_generated=false" >> $GITHUB_OUTPUT
            echo "::warning::Profile data not generated"
          fi

      - name: Upload profile data
        if: steps.profiling.outputs.profile_generated == 'true'
        uses: actions/upload-artifact@v6
        with:
          name: performance-profile-${{ github.run_number }}
          path: samply-profile.json
          retention-days: 30

  benchmark:
    name: Benchmark Tests
    runs-on: ubicloud-standard-2
    timeout-minutes: 45
    env:
      FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Setup Rust environment
        uses: ./.github/actions/setup
        with:
          rust-version: stable
          cache-shared-key: bench-${{ hashFiles('**/Cargo.lock') }}
          github-token: ${{ secrets.GITHUB_TOKEN }}
          cache-save-if: ${{ github.ref == 'refs/heads/main' }}

      - name: Run benchmarks
        run: |
          cargo bench --package ecstore --bench comparison_benchmark -- --output-format json | \
          tee benchmark-results.json

      - name: Upload benchmark results
        uses: actions/upload-artifact@v6
        with:
          name: benchmark-results-${{ github.run_number }}
          path: benchmark-results.json
          retention-days: 7
