#!/bin/bash
# Nightly training script for mjlab benchmarks
#
# This script clones mjlab fresh, runs the tracking benchmark, and generates a report.
# It is designed to be called by a systemd timer or cron job.
#
# Usage:
#   ./scripts/benchmarks/nightly_train.sh
#
# Environment variables:
#   CUDA_DEVICE: GPU device to use (default: 0)
#   WANDB_TAGS: Comma-separated tags for the run (default: nightly)
#   SKIP_TRAINING: Set to "1" to skip training and only generate report
#   SKIP_THROUGHPUT: Set to "1" to skip throughput benchmarking

set -euo pipefail

# Configuration
CUDA_DEVICE="${CUDA_DEVICE:-0}"
WANDB_TAGS="${WANDB_TAGS:-(\"nightly\",)}"
SKIP_TRAINING="${SKIP_TRAINING:-0}"
SKIP_THROUGHPUT="${SKIP_THROUGHPUT:-0}"

# Training configuration
TASK="Mjlab-Tracking-Flat-Unitree-G1"
NUM_ENVS=4096
MAX_ITERATIONS=6000
REGISTRY_NAME="rll_humanoid/wandb-registry-Motions/side_kick_test"

REPO_URL="git@github.com:mujocolab/mjlab.git"
GH_PAGES_BRANCH="gh-pages"
WORK_DIR="/tmp/mjlab-nightly-$$"
GH_PAGES_DIR="/tmp/mjlab-gh-pages-$$"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

error() {
    log "ERROR: $*" >&2
    exit 1
}

clear_gpu() {
    local gpu_device="$1"
    log "Clearing GPU $gpu_device..."
    gpu_pids=$(nvidia-smi --query-compute-apps=pid --format=csv,noheader,nounits -i "$gpu_device" 2>/dev/null || true)
    if [[ -n "$gpu_pids" ]]; then
        for pid in $gpu_pids; do
            log "Killing process $pid on GPU $gpu_device"
            kill -9 "$pid" 2>/dev/null || true
        done
        sleep 2  # Wait for processes to fully terminate
    fi
}

cleanup() {
    if [[ -d "$WORK_DIR" ]]; then
        log "Cleaning up work directory..."
        rm -rf "$WORK_DIR"
    fi
    if [[ -d "$GH_PAGES_DIR" ]]; then
        log "Cleaning up gh-pages clone..."
        rm -rf "$GH_PAGES_DIR"
    fi
}
trap cleanup EXIT

export GIT_SSH_COMMAND="ssh -i \"$HOME/.ssh/mjlab_nightly_ed25519\" \
    -o IdentitiesOnly=yes \
    -o StrictHostKeyChecking=accept-new"

# Clone fresh copy of mjlab
log "Cloning mjlab..."
git clone "$REPO_URL" "$WORK_DIR"
cd "$WORK_DIR"

log "Starting nightly benchmark run"
log "Task: $TASK"
log "GPU: $CUDA_DEVICE"
log "Commit: $(git rev-parse HEAD)"

# Run training
if [[ "$SKIP_TRAINING" != "1" ]]; then
    log "Starting training..."

    clear_gpu "$CUDA_DEVICE"

    CUDA_VISIBLE_DEVICES="$CUDA_DEVICE" uv run train "$TASK" \
        --env.scene.num-envs "$NUM_ENVS" \
        --agent.max-iterations "$MAX_ITERATIONS" \
        --registry-name "$REGISTRY_NAME" \
        --agent.wandb-tags "$WANDB_TAGS"

    log "Training completed"
else
    log "Skipping training (SKIP_TRAINING=1)"
fi

# Clone gh-pages branch (shallow clone for speed)
log "Cloning gh-pages branch..."
if git ls-remote --exit-code --heads origin "$GH_PAGES_BRANCH" > /dev/null 2>&1; then
    git clone --branch "$GH_PAGES_BRANCH" --depth 1 "$REPO_URL" "$GH_PAGES_DIR"
else
    # Create new gh-pages branch
    mkdir -p "$GH_PAGES_DIR"
    cd "$GH_PAGES_DIR"
    git init
    git remote add origin "$REPO_URL"
    git checkout -b "$GH_PAGES_BRANCH"
    cd "$WORK_DIR"
fi

# Copy cached data if exists
REPORT_DIR="$GH_PAGES_DIR/nightly"
mkdir -p "$REPORT_DIR"

# Run throughput benchmark
if [[ "$SKIP_THROUGHPUT" != "1" ]]; then
    log "Running throughput benchmark..."

    clear_gpu "$CUDA_DEVICE"

    CUDA_VISIBLE_DEVICES="$CUDA_DEVICE" uv run python scripts/benchmarks/measure_throughput.py \
        --num-envs "$NUM_ENVS" \
        --output-dir "$REPORT_DIR"
    log "Throughput benchmark completed"
else
    log "Skipping throughput benchmark (SKIP_THROUGHPUT=1)"
fi

# Generate report (uses cached data.json if present, only evaluates new runs)
log "Generating benchmark report..."
uv run python scripts/benchmarks/generate_report.py \
    --entity gcbc_researchers \
    --tag nightly \
    --output-dir "$REPORT_DIR"

log "Report generated"

# Commit and push
cd "$GH_PAGES_DIR"
git add -A
if git diff --staged --quiet; then
    log "No changes to commit"
else
    git commit -m "Update nightly tracking benchmark $(date '+%Y-%m-%d')"
    git push origin "$GH_PAGES_BRANCH" || log "Failed to push"
    log "Deployed to GitHub Pages"
fi

log "Nightly benchmark complete"
