#!/bin/bash
# modules/git-utils.sh - Git-related functions

# Get current git commit hash (short version)
function get_git_commit() {
  if git rev-parse --git-dir > /dev/null 2>&1; then
    git rev-parse --short=8 HEAD
  else
    print_error "Error: Not in a git repository"
    exit 1
  fi
}

# Get current git branch
function get_git_branch() {
  if git rev-parse --git-dir > /dev/null 2>&1; then
    git rev-parse --abbrev-ref HEAD
  else
    echo "main"
  fi
}

# Get latest git tag
function get_latest_tag() {
  if git rev-parse --git-dir > /dev/null 2>&1; then
    git describe --tags --abbrev=0 2>/dev/null || echo ""
  else
    echo ""
  fi
}

# Check if current commit is tagged
function is_on_tagged_commit() {
  local latest_tag=$(get_latest_tag)
  if [[ -n "$latest_tag" ]]; then
    local tag_commit=$(git rev-list -n 1 "$latest_tag")
    local current_commit=$(git rev-parse HEAD)
    [[ "$tag_commit" == "$current_commit" ]]
  else
    return 1
  fi
}

# Check if we should deploy based on configuration
function should_deploy() {
  # Set DEPLOY_ON_TAGS=true in .env to only deploy on git tags
  if [[ "$DEPLOY_ON_TAGS" == "true" ]]; then
    if is_on_tagged_commit; then
      print_success "On tagged commit: $(get_latest_tag)"
      return 0
    else
      echo "${STATUS_TAG} Not on a tagged commit, skipping deployment"
      print_info "Create a tag to trigger deployment: git tag v1.0.0 && git push --tags"
      return 1
    fi
  else
    # Deploy on any commit (current behavior)
    return 0
  fi
}

# Check for uncommitted git changes
function has_git_changes() {
  # Check if there are uncommitted changes
  if ! git diff-index --quiet HEAD --; then
    print_warning "Warning: You have uncommitted changes"
    echo "${STATUS_ANALYZE} Uncommitted files:"
    git diff --name-only HEAD
    echo ""
    read -p "Continue with deployment? (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
      print_error "Deployment cancelled"
      exit 1
    fi
  fi
}

# Build Lambda S3 key with git metadata
function build_lambda_s3_key() {
  local commit_hash=$(get_git_commit)
  local branch=$(get_git_branch)
  local timestamp=$(date '+%Y%m%d-%H%M%S')
  
  # If on a tagged commit, use tag in path
  local latest_tag=$(get_latest_tag)
  if [[ -n "$latest_tag" ]] && is_on_tagged_commit; then
    echo "releases/${latest_tag}/${commit_hash}/${timestamp}/lambda-function.zip"
  else
    echo "builds/${branch}/${commit_hash}/${timestamp}/lambda-function.zip"
  fi
}

# Watch git repository for changes
function watch_git() {
  echo "${STATUS_WATCH} Watching git repository for changes..."
  
  if [[ "$DEPLOY_ON_TAGS" == "true" ]]; then
    echo "${STATUS_TAG} Tag-based deployment enabled - will only deploy on git tags"
  else
    echo "${STATUS_RELOAD} Commit-based deployment enabled - will deploy on any commit"
  fi
  
  # Initial deployment attempt (never stops watching if it fails)
  if [[ ! -f "$HASH_FILE" ]] || has_version_changed; then
    echo "${STATUS_RELOAD} New commit detected or initial deployment"
    safe_deploy_stack
  else
    echo "${STATUS_DATA} No new commits detected - watching for changes..."
  fi
  
  # Main watch loop - this should NEVER exit due to errors
  echo ""
  echo "${STATUS_WATCH} Script is now watching for git changes..."
  echo "   • Make commits and see automatic deployments"
  echo "   • Fix any errors and commit again to retry"
  echo "   • Press Ctrl+C to stop watching"
  echo ""
  
  while true; do
    # Use fswatch with timeout to make the loop more robust
    if timeout $FSWATCH_TIMEOUT fswatch -1 .git/HEAD .git/refs/ . --exclude=".git/logs" --exclude="node_modules" --exclude=".env*" >/dev/null 2>&1; then
      echo ""
      echo "📝 Git repository change detected at $(date)"
      
      # Check if it's actually a new commit
      if has_version_changed; then
        echo "${STATUS_RELOAD} New commit detected, starting deployment..."
        safe_deploy_stack
      else
        echo "${STATUS_ANALYZE} File change detected but no new commits, continuing to watch..."
      fi
    else
      # If fswatch times out or fails, just continue the loop
      # This prevents the script from hanging if fswatch has issues
      continue
    fi
    
    echo ""
    echo "${STATUS_WATCH} Continuing to watch for changes..."
    echo "   • Status: Ready for next commit"
    echo "   • Time: $(date)"
  done
}