#!/bin/bash
set -euo pipefail

# Usage: ./analysis/run-fuzzing.sh [--help] <optimizer> [runs=N] [buybias=N] [trades=N] [uncapped=bool] [ci=N] [as=N] [aw=N] [dd=N] [debugCSV]

show_help() {
    cat <<'EOF'
Usage: ./analysis/run-fuzzing.sh [--help] <optimizer> [runs=N] [buybias=N] [trades=N] [uncapped=bool] [ci=N] [as=N] [aw=N] [dd=N] [debugCSV]

Run StreamlinedFuzzing against a named optimizer. Each run generates a CSV file
with per-trade position snapshots for analysis. Includes random stake/unstake
actions (~10% of trades).

Arguments:
  optimizer     Required. One of: BullMarketOptimizer, BearMarketOptimizer,
                NeutralMarketOptimizer, WhaleOptimizer, ExtremeOptimizer,
                MaliciousOptimizer, ConfigurableOptimizer
  runs=N        Number of fuzzing runs (default: 20)
  buybias=N     Buy probability 0-100% (default: 50)
  trades=N      Trades per run (default: 15)
  uncapped=true Enable uncapped swaps (default: false)
  debugCSV      Run 3 short runs and launch the HTML visualizer

ConfigurableOptimizer params (only used when optimizer=ConfigurableOptimizer):
  ci=N          Capital inefficiency (uint256, default: 0)
  as=N          Anchor share (uint256, default: 100000000000000000)
  aw=N          Anchor width in ticks (uint24, default: 20, max 100)
  dd=N          Discovery depth (uint256, default: 500000000000000000)

Examples:
  ./analysis/run-fuzzing.sh BullMarketOptimizer
  ./analysis/run-fuzzing.sh WhaleOptimizer runs=100 trades=50
  ./analysis/run-fuzzing.sh BearMarketOptimizer buybias=80
  ./analysis/run-fuzzing.sh BullMarketOptimizer debugCSV
  ./analysis/run-fuzzing.sh ConfigurableOptimizer ci=0 as=100000000000000000 aw=20 dd=500000000000000000 runs=200 trades=100 uncapped=true
EOF
    exit 0
}

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Handle --help
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
    show_help
fi

# Configuration
OPTIMIZER=${1:-BullMarketOptimizer}

# Check if second parameter is debugCSV
DEBUG_CSV=false
if [[ "${2:-}" == "debugCSV" ]]; then
    DEBUG_CSV=true
    RUNS_VALUE=3
    BUYBIAS_VALUE=50
    TRADES_VALUE=5
    UNCAPPED_VALUE=false
    CI_VALUE=0
    AS_VALUE=100000000000000000
    AW_VALUE=20
    DD_VALUE=500000000000000000
else
    # Parse key=value parameters from remaining args
    RUNS_VALUE=20
    BUYBIAS_VALUE=50
    TRADES_VALUE=15
    UNCAPPED_VALUE=false
    CI_VALUE=0
    AS_VALUE=100000000000000000
    AW_VALUE=20
    DD_VALUE=500000000000000000

    shift || true  # skip optimizer arg
    for arg in "$@"; do
        case "$arg" in
            runs=*)      RUNS_VALUE=${arg#runs=} ;;
            buybias=*)   BUYBIAS_VALUE=${arg#buybias=} ;;
            trades=*)    TRADES_VALUE=${arg#trades=} ;;
            uncapped=*)  UNCAPPED_VALUE=${arg#uncapped=} ;;
            ci=*)        CI_VALUE=${arg#ci=} ;;
            as=*)        AS_VALUE=${arg#as=} ;;
            aw=*)        AW_VALUE=${arg#aw=} ;;
            dd=*)        DD_VALUE=${arg#dd=} ;;
            debugCSV)    DEBUG_CSV=true; RUNS_VALUE=3; TRADES_VALUE=5 ;;
            *)           echo -e "${RED}Unknown parameter: $arg${NC}"; show_help ;;
        esac
    done
fi

# Ensure we're in the onchain directory
cd "$(dirname "$0")/.."

echo -e "${GREEN}=== Fuzzing Analysis ===${NC}"
echo "Optimizer: $OPTIMIZER"
echo "Total runs: $RUNS_VALUE"
echo "Trades per run: $TRADES_VALUE"
echo "Buy bias: $BUYBIAS_VALUE%"
echo "Uncapped: $UNCAPPED_VALUE"
if [ "$OPTIMIZER" = "ConfigurableOptimizer" ]; then
    echo "CI: $CI_VALUE  AS: $AS_VALUE  AW: $AW_VALUE  DD: $DD_VALUE"
fi
echo ""

# Validate optimizer
case $OPTIMIZER in
    BullMarketOptimizer|BearMarketOptimizer|NeutralMarketOptimizer|WhaleOptimizer|ExtremeOptimizer|MaliciousOptimizer|ConfigurableOptimizer)
        ;;
    *)
        echo -e "${RED}Error: Invalid optimizer class '$OPTIMIZER'${NC}"
        echo "Valid: BullMarketOptimizer, BearMarketOptimizer, NeutralMarketOptimizer, WhaleOptimizer, ExtremeOptimizer, MaliciousOptimizer, ConfigurableOptimizer"
        exit 1
        ;;
esac

# Record existing CSV files before running
EXISTING_CSVS=$(ls -1 analysis/fuzz-????-???.csv 2>/dev/null | sort || true)

echo -e "${YELLOW}Starting fuzzing analysis...${NC}"
echo ""

FUZZING_RUNS=$RUNS_VALUE \
OPTIMIZER_CLASS=$OPTIMIZER \
BUY_BIAS=$BUYBIAS_VALUE \
TRADES_PER_RUN=$TRADES_VALUE \
UNCAPPED_SWAPS=$UNCAPPED_VALUE \
CI_VALUE=$CI_VALUE \
AS_VALUE=$AS_VALUE \
AW_VALUE=$AW_VALUE \
DD_VALUE=$DD_VALUE \
forge script analysis/StreamlinedFuzzing.s.sol:StreamlinedFuzzing --skip-simulation --gas-estimate-multiplier 300 -vv 2>&1

echo ""
echo -e "${GREEN}=== ANALYSIS COMPLETE ===${NC}"

# Find newly generated CSV files
NEW_CSVS=$(ls -1 analysis/fuzz-????-???.csv 2>/dev/null | sort || true)
if [ "$EXISTING_CSVS" != "$NEW_CSVS" ]; then
    SCENARIO_CODE=$(echo "$NEW_CSVS" | grep -v -F "$EXISTING_CSVS" 2>/dev/null | head -1 | sed 's|.*/fuzz-\(....\).*|\1|' || echo "UNKN")
else
    SCENARIO_CODE="UNKN"
fi

CSV_COUNT=$(ls -1 analysis/fuzz-${SCENARIO_CODE}-*.csv 2>/dev/null | wc -l || true)
echo "Generated $CSV_COUNT CSV files with scenario ID: ${SCENARIO_CODE}"

# Check for profitable scenarios
echo ""
echo -e "${YELLOW}=== Checking for Profitable Scenarios ===${NC}"
PROFITABLE_COUNT=0
for csv in analysis/fuzz-${SCENARIO_CODE}-*.csv; do
    if [ -f "$csv" ]; then
        INIT_ETH=$(grep "^INIT," "$csv" | cut -d',' -f13 || true)
        FINAL_ETH=$(grep "^FINAL," "$csv" | cut -d',' -f13 || true)

        if [ -n "$INIT_ETH" ] && [ -n "$FINAL_ETH" ]; then
            if [ "$FINAL_ETH" -gt "$INIT_ETH" ] 2>/dev/null; then
                PROFIT_PCT=$(echo "scale=1; ($FINAL_ETH - $INIT_ETH) * 100 / $INIT_ETH" | bc -l 2>/dev/null || echo "?")
                echo -e "${GREEN}  $csv: PROFITABLE (+${PROFIT_PCT}%)${NC}"
                ((PROFITABLE_COUNT++)) || true
            fi
        fi
    fi
done

if [ $PROFITABLE_COUNT -eq 0 ]; then
    echo "  No profitable scenarios found"
else
    echo -e "${GREEN}Found $PROFITABLE_COUNT profitable scenarios${NC}"
fi

echo ""
echo -e "${GREEN}CSV files generated with scenario ID: ${SCENARIO_CODE}${NC}"

# Launch HTML visualizer if debugCSV mode
if [ "$DEBUG_CSV" = true ]; then
    echo ""
    echo -e "${YELLOW}Launching HTML visualizer...${NC}"

    if command -v python3 &> /dev/null; then
        echo "Starting local server at http://localhost:8000"
        echo "Open http://localhost:8000/run-visualizer.html to view results"
        cd analysis
        python3 -m http.server 8000 --bind 127.0.0.1 &
        SERVER_PID=$!

        sleep 1
        if command -v open &> /dev/null; then
            open "http://localhost:8000/run-visualizer.html"
        elif command -v xdg-open &> /dev/null; then
            xdg-open "http://localhost:8000/run-visualizer.html"
        fi

        echo ""
        echo "Press Ctrl+C to stop the server"
        wait $SERVER_PID
    else
        echo "Python3 not found. To view results:"
        echo "  cd analysis && python3 -m http.server 8000"
        echo "  Then open http://localhost:8000/run-visualizer.html"
    fi
fi
