#!/bin/bash
# gemini-review.sh
# CLI script for reviewing git diffs with Gemini

# Define colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

# Display progress spinner
function spinner {
  local pid=$1
  local delay=0.1
  local spinstr='|/-\'
  while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
    local temp=${spinstr#?}
    printf " [%c]  " "$spinstr"
    local spinstr=$temp${spinstr%"$temp"}
    sleep $delay
    printf "\b\b\b\b\b\b"
  done
  printf "    \b\b\b\b"
}

# Display help information
function show_help {
  echo -e "${BLUE}Gemini Code Review CLI${NC}"
  echo "Usage: gemini-review [options] [git-diff-args]"
  echo ""
  echo "Options:"
  echo "  --focus=FOCUS     Focus of the review: security, performance, architecture, bugs, general (default)"
  echo "  --model=MODEL     Gemini model to use (defaults to server configuration)"
  echo "  --reasoning=LEVEL Reasoning effort: none, low, medium (default), high"
  echo "  --exclude=PATTERN Files to exclude (glob pattern, can be repeated)"
  echo "  --help            Show this help message"
  echo ""
  echo "Examples:"
  echo "  gemini-review                             # Review all uncommitted changes"
  echo "  gemini-review --focus=security HEAD~3..   # Security review of last 3 commits"
  echo "  gemini-review src/                        # Review changes in src directory"
  echo "  gemini-review --reasoning=high            # In-depth review with high reasoning effort"
  echo ""
}

# Set default values
SERVER_URL="http://localhost:3000"
FOCUS="general"
MODEL="gemini-flash-2.0"  # Default to the cheaper Gemini Flash 2.0 model
REASONING="medium"
EXCLUDE_PATTERNS=""

# Parse command line arguments
while [[ $# -gt 0 ]]; do
  case $1 in
    --help)
      show_help
      exit 0
      ;;
    --focus=*)
      FOCUS="${1#*=}"
      if [[ ! "$FOCUS" =~ ^(security|performance|architecture|bugs|general)$ ]]; then
        echo -e "${RED}Error: Invalid focus '${FOCUS}'${NC}"
        echo "Valid options: security, performance, architecture, bugs, general"
        exit 1
      fi
      shift
      ;;
    --model=*)
      MODEL="${1#*=}"
      shift
      ;;
    --reasoning=*)
      REASONING="${1#*=}"
      if [[ ! "$REASONING" =~ ^(none|low|medium|high)$ ]]; then
        echo -e "${RED}Error: Invalid reasoning level '${REASONING}'${NC}"
        echo "Valid options: none, low, medium, high"
        exit 1
      fi
      shift
      ;;
    --exclude=*)
      if [ -z "$EXCLUDE_PATTERNS" ]; then
        EXCLUDE_PATTERNS="\"${1#*=}\""
      else
        EXCLUDE_PATTERNS="$EXCLUDE_PATTERNS,\"${1#*=}\""
      fi
      shift
      ;;
    --server=*)
      SERVER_URL="${1#*=}"
      shift
      ;;
    *)
      # Save remaining args for git diff
      break
      ;;
  esac
done

# Prepare URL parameters
URL_PARAMS="reviewFocus=$FOCUS&reasoningEffort=$REASONING"
if [ ! -z "$MODEL" ]; then
  URL_PARAMS="$URL_PARAMS&model=$MODEL"
fi
if [ ! -z "$EXCLUDE_PATTERNS" ]; then
  URL_PARAMS="$URL_PARAMS&excludePatterns=[$EXCLUDE_PATTERNS]"
fi

# Display review information
echo -e "${BLUE}Generating code review using Gemini...${NC}"
echo "Focus: $FOCUS"
echo "Reasoning effort: $REASONING"
if [ ! -z "$MODEL" ]; then
  echo "Model: $MODEL"
else
  echo "Model: Using server default"
fi
if [ ! -z "$EXCLUDE_PATTERNS" ]; then
  echo "Excluding: $EXCLUDE_PATTERNS"
fi

# Generate the diff and send to the API
echo -e "${YELLOW}Fetching git diff...${NC}"

# Use git diff with any remaining args, or default to all uncommitted changes
DIFF_COMMAND="git diff"
if [ $# -gt 0 ]; then
  DIFF_COMMAND="$DIFF_COMMAND $@"
fi

DIFF_OUTPUT=$(eval "$DIFF_COMMAND")

# Check if there's any diff output
if [ -z "$DIFF_OUTPUT" ]; then
  echo -e "${YELLOW}No changes detected in the specified range.${NC}"
  exit 0
fi

# Check diff size and warn or exit if too large
DIFF_LENGTH=${#DIFF_OUTPUT}
MAX_SIZE_KB=1024  # 1MB limit (same as default in GeminiGitDiffService)
DIFF_SIZE_KB=$(($DIFF_LENGTH / 1024))
echo "Diff size: $DIFF_SIZE_KB KB"

if [ $DIFF_SIZE_KB -gt $MAX_SIZE_KB ]; then
  echo -e "${RED}Warning: Diff size exceeds recommended limit ($DIFF_SIZE_KB KB > $MAX_SIZE_KB KB)${NC}"
  echo "Large diffs may result in incomplete review or API errors."
  read -p "Continue anyway? (y/n) " -n 1 -r
  echo
  if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    echo "Operation cancelled."
    exit 1
  fi
fi

# Send request to the API
echo -e "${YELLOW}Sending to Gemini for analysis...${NC}"

# Use curl to send the request and store the response
TEMP_FILE=$(mktemp)
(curl -s -X POST \
  -H "Content-Type: text/plain" \
  --data-binary "$DIFF_OUTPUT" \
  "$SERVER_URL/api/tools/geminiGitLocalDiffReview?$URL_PARAMS" > "$TEMP_FILE") &

# Show spinner while waiting
spinner $!

# Check if the request was successful
if [ ! -s "$TEMP_FILE" ]; then
  echo -e "${RED}Error: No response received from the server.${NC}"
  echo "Please check that the server is running at $SERVER_URL"
  rm "$TEMP_FILE"
  exit 1
fi

# Extract and display the review
REVIEW=$(jq -r '.review' "$TEMP_FILE")
MODEL_USED=$(jq -r '.model' "$TEMP_FILE")
EXECUTION_TIME=$(jq -r '.executionTime' "$TEMP_FILE")

echo -e "${GREEN}Review completed!${NC}"
echo "Model used: $MODEL_USED"
echo "Execution time: $(($EXECUTION_TIME / 1000)).$(($EXECUTION_TIME % 1000)) seconds"
echo ""
echo -e "${BLUE}=== CODE REVIEW ====${NC}"
echo "$REVIEW"

# Clean up
rm "$TEMP_FILE"