# Deploys a job to the slurm cluster and live-prints the output. Usage:
# ./deploy.sh [--gpus N] python program.py [script_args...]
# ./deploy.sh [--gpus N] pytest 
# Requires .env file with CONDA_ENV_NAME set
# Note that if you cancel this script it will not kill the job.

# Initialize default GPU count
GPUS=1

# Parse arguments for --gpus
while [[ $# -gt 0 ]]; do
    case $1 in
        --gpus)
            GPUS="$2"
            shift 2
            ;;
        *)
            break
            ;;
    esac
done

# Check if required argument is provided
if [ "$#" -lt 1 ]; then
    echo "Usage: $0 [--gpus N] <script_path> [script_args...]"
    exit 1
fi

source .env
# Assert that CONDA_ENV_NAME is defined
if [ -z "$CONDA_ENV_NAME" ]; then
    echo "Error: CONDA_ENV_NAME is not defined in the .env file."
    exit 1
fi

# Create a temporary sbatch file
TMP_SBATCH=$(mktemp)
LOG_DIR="$(dirname "$(realpath "$0")")/logs"

cat << EOF > $TMP_SBATCH
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --gpus-per-node=$GPUS
#SBATCH --mem=1000gb
#SBATCH --time=2:00:00
#SBATCH --partition=high_priority
#SBATCH --job-name=dd-deploy
#SBATCH --output=$LOG_DIR/dd-deploy-%j.out

start_time=\$(date +%s)

shopt -s expand_aliases
source ~/.bashrc
conda activate $CONDA_ENV_NAME
cd "$(pwd)"
$@

# Print the elapsed time
end_time=\$(date +%s)
elapsed_time=\$((\$end_time - \$start_time))
minutes=\$((\$elapsed_time / 60))
seconds=\$((\$elapsed_time % 60))
printf "Elapsed Time: %02dm %02ds\n" \$minutes \$seconds
EOF

echo "Deploying with $GPUS GPU(s): $@"
# Submit the job and capture the job ID
JOB_ID=$(sbatch --parsable $TMP_SBATCH)

# Clean up the temporary file
rm $TMP_SBATCH

# Function to check if the job is still running
job_is_running() {
    squeue -j $JOB_ID -h -o "%t" | grep -q "R"
}

# Path to the output file
OUTPUT_FILE="$LOG_DIR/dd-deploy-$JOB_ID.out"

echo "Job submitted with ID: $JOB_ID. Waiting for start..."

# Wait for the job to start and the output file to be created
while ! job_is_running || [ ! -f "$OUTPUT_FILE" ]; do
    sleep 1
done

# Live print the output until the job is finished
echo "Job started. Printing live output:"
echo "----------------------------------------"
tail -f "$OUTPUT_FILE" &
TAIL_PID=$!

# Wait for the job to complete
while job_is_running || [ -z "$(tail -n 1 "$OUTPUT_FILE" | grep "Elapsed Time")" ]; do
    sleep 1
done

# Stop the tail process
kill $TAIL_PID

echo "----------------------------------------"