#!/usr/bin/env bash

set -e

# Variables to hold search string, targets, ignored paths, and flags
search_string=""
targets=()
ignore=()
match_start=false # default: do not restrict to start of line

# --- Parse command-line arguments ---
while [[ $# -gt 0 ]]; do
	case "$1" in
	-i | --ignore)
		shift
		while [[ $# -gt 0 && ! "$1" =~ ^- ]]; do
			ignore+=("$1")
			shift
		done
		;;
	-b | --begin)
		match_start=true
		shift
		;;
	*)
		if [[ -z "$search_string" ]]; then
			search_string="$1"
		else
			targets+=("$1")
		fi
		shift
		;;
	esac
done

# --- Prompt for search string if missing ---
if [[ -z "$search_string" ]]; then
	read -rp "Text to search for: " search_string
	# Remove surrounding quotes if present
	if [[ "$search_string" =~ ^\"(.*)\"$ ]]; then
		search_string="${BASH_REMATCH[1]}"
	elif [[ "$search_string" =~ ^\'(.*)\'$ ]]; then
		search_string="${BASH_REMATCH[1]}"
	fi
fi

# --- Default targets to . if none provided ---
if [[ ${#targets[@]} -eq 0 ]]; then
	targets=(".")
fi

# --- Prompt for ignore paths if none provided via CLI ---
if [[ ${#ignore[@]} -eq 0 ]]; then
	read -rp "Files/directories to ignore (space-separated, optional): " ignore_input
	if [[ -n "$ignore_input" ]]; then
		for item in $ignore_input; do
			if [[ "$item" =~ ^\"(.*)\"$ ]]; then
				ignore+=("${BASH_REMATCH[1]}")
			elif [[ "$item" =~ ^\'(.*)\'$ ]]; then
				ignore+=("${BASH_REMATCH[1]}")
			else
				ignore+=("$item")
			fi
		done
	fi
fi

# --- Build find command ---
cmd=(find "${targets[@]}")

# Exclude ignored directories/files
if [[ ${#ignore[@]} -gt 0 ]]; then
	prune_expr=()
	for ign in "${ignore[@]}"; do
		prune_expr+=(-name "$ign" -prune -o)
	done
	cmd+=("${prune_expr[@]}")
fi

# Always search files
cmd+=(-type f -print)

# --- Prepare grep pattern ---
if $match_start; then
	# Escape regex special chars in search string
	escaped_search=$(printf '%s\n' "$search_string" | sed 's/[][\.*^$(){}?+|/]/\\&/g')
	pattern="^$escaped_search"
	grep_opts="-Hn"
else
	pattern="$search_string"
	grep_opts="-HnF"
fi

# --- Execute find and search content ---
"${cmd[@]}" 2>/dev/null | xargs grep $grep_opts -- "$pattern" 2>/dev/null
