#!/bin/sh
# LocalRecall Memory Controller
# Persistent memory for AI agents

VERSION="1.0.0"
CONFIG="localrecall"

# Load libraries
. /usr/lib/localrecall/memory.sh
. /usr/lib/localrecall/ai.sh

usage() {
	cat <<EOF
LocalRecall Memory Controller v$VERSION

Usage: $(basename "$0") <command> [options]

Commands:
  status              Show memory status
  add <cat> <content> Add a memory (category: threats|decisions|patterns|configs|conversations)
  get <id>            Get memory by ID
  search <query>      Search memories by content
  list [category]     List memories (optionally by category)
  recent [N]          Show N most recent memories (default: 20)
  important [N]       Show important memories (importance >= 7)
  delete <id>         Delete a memory
  cleanup             Cleanup old memories
  export <file>       Export memories to file
  import <file>       Import memories from file
  summarize [cat]     AI-summarize memories
  context <agent>     Get context for an agent
  stats               Show memory statistics

Options:
  -a, --agent <name>  Specify agent name (default: user)
  -i, --importance N  Set importance (1-10, default: 5)
  -j, --json          Output in JSON format
  -q, --quiet         Suppress output

Examples:
  $(basename "$0") add threats "Detected SQL injection attempt from 192.168.1.100"
  $(basename "$0") search "SQL injection"
  $(basename "$0") context threat_analyst
  $(basename "$0") summarize threats
EOF
}

uci_get() {
	uci -q get "${CONFIG}.$1"
}

cmd_status() {
	local json_mode="$1"

	local enabled=$(uci_get main.enabled)
	local storage=$(uci_get main.storage_path)
	local max_mem=$(uci_get main.max_memories)

	local total=$(count_memories)
	local threats=$(count_category threats)
	local decisions=$(count_category decisions)
	local patterns=$(count_category patterns)

	local localai_status="offline"
	check_localai && localai_status="online"

	local storage_size="0"
	[ -d "$storage" ] && storage_size=$(du -sh "$storage" 2>/dev/null | cut -f1)

	if [ "$json_mode" = "1" ]; then
		cat <<EOF
{
	"enabled": $([ "$enabled" = "1" ] && echo "true" || echo "false"),
	"total_memories": $total,
	"threats": $threats,
	"decisions": $decisions,
	"patterns": $patterns,
	"max_memories": ${max_mem:-1000},
	"storage_path": "${storage:-/var/lib/localrecall}",
	"storage_size": "$storage_size",
	"localai_status": "$localai_status"
}
EOF
	else
		echo "LocalRecall Memory Status"
		echo "========================="
		echo "Enabled:       $([ "$enabled" = "1" ] && echo "Yes" || echo "No")"
		echo "Total:         $total memories"
		echo "  Threats:     $threats"
		echo "  Decisions:   $decisions"
		echo "  Patterns:    $patterns"
		echo "Max:           ${max_mem:-1000}"
		echo "Storage:       ${storage:-/var/lib/localrecall} ($storage_size)"
		echo "LocalAI:       $localai_status"
	fi
}

cmd_add() {
	local category="$1"
	local content="$2"
	local agent="${AGENT:-user}"
	local importance="${IMPORTANCE:-5}"

	if [ -z "$category" ] || [ -z "$content" ]; then
		echo "Error: Category and content required"
		echo "Usage: localrecallctl add <category> <content>"
		return 1
	fi

	# Validate category
	case "$category" in
		threats|decisions|patterns|configs|conversations) ;;
		*)
			echo "Error: Invalid category. Use: threats|decisions|patterns|configs|conversations"
			return 1
			;;
	esac

	local id=$(add_memory "$category" "$agent" "$content" '{}' "$importance")
	echo "Memory added: $id"
}

cmd_get() {
	local id="$1"

	if [ -z "$id" ]; then
		echo "Error: Memory ID required"
		return 1
	fi

	local memory=$(get_memory "$id")
	if [ -n "$memory" ]; then
		echo "$memory"
	else
		echo "Memory not found: $id"
		return 1
	fi
}

cmd_search() {
	local query="$1"
	local limit="${2:-20}"

	if [ -z "$query" ]; then
		echo "Error: Search query required"
		return 1
	fi

	echo "Searching for: $query"
	echo "---"
	search_content "$query" "$limit"
}

cmd_list() {
	local category="$1"
	local limit="${2:-50}"

	if [ -n "$category" ]; then
		echo "Memories in category: $category"
		echo "---"
		search_category "$category" "$limit"
	else
		echo "All memories (last $limit)"
		echo "---"
		get_recent "$limit"
	fi
}

cmd_recent() {
	local limit="${1:-20}"
	echo "Recent memories (last $limit)"
	echo "---"
	get_recent "$limit"
}

cmd_important() {
	local limit="${1:-50}"
	echo "Important memories (importance >= 7)"
	echo "---"
	get_important "$limit"
}

cmd_delete() {
	local id="$1"

	if [ -z "$id" ]; then
		echo "Error: Memory ID required"
		return 1
	fi

	delete_memory "$id"
	echo "Memory deleted: $id"
}

cmd_cleanup() {
	local retention=$(uci_get main.retention_days)
	local keep_imp=$(uci_get cleanup.keep_important)

	echo "Cleaning up memories older than ${retention:-90} days..."
	local deleted=$(cleanup_old "${retention:-90}" "${keep_imp:-1}")
	echo "Deleted: $deleted memories"
}

cmd_export() {
	local file="$1"

	if [ -z "$file" ]; then
		echo "Error: Output file required"
		return 1
	fi

	export_memories "$file"
	echo "Memories exported to: $file"
}

cmd_import() {
	local file="$1"

	if [ -z "$file" ]; then
		echo "Error: Input file required"
		return 1
	fi

	if [ ! -f "$file" ]; then
		echo "Error: File not found: $file"
		return 1
	fi

	import_memories "$file"
	echo "Memories imported from: $file"
}

cmd_summarize() {
	local category="$1"

	if ! check_localai; then
		echo "Error: LocalAI not available"
		return 1
	fi

	echo "Summarizing memories..."
	echo "---"
	summarize_memories "$category"
}

cmd_context() {
	local agent="$1"

	if [ -z "$agent" ]; then
		echo "Error: Agent name required"
		return 1
	fi

	get_agent_context "$agent" ""
}

cmd_stats() {
	local total=$(count_memories)
	local threats=$(count_category threats)
	local decisions=$(count_category decisions)
	local patterns=$(count_category patterns)
	local configs=$(count_category configs)
	local convs=$(count_category conversations)

	echo "Memory Statistics"
	echo "================="
	echo "Total:         $total"
	echo ""
	echo "By Category:"
	echo "  Threats:       $threats"
	echo "  Decisions:     $decisions"
	echo "  Patterns:      $patterns"
	echo "  Configs:       $configs"
	echo "  Conversations: $convs"
	echo ""

	# Agent breakdown
	echo "By Agent:"
	for agent in threat_analyst dns_guard network_anomaly cve_triage user; do
		local count=$(search_agent "$agent" 9999 | wc -l)
		[ "$count" -gt 0 ] && echo "  $agent: $count"
	done
}

# Parse global options
AGENT="user"
IMPORTANCE=5
JSON=0
QUIET=0

while [ $# -gt 0 ]; do
	case "$1" in
		-a|--agent)
			AGENT="$2"
			shift 2
			;;
		-i|--importance)
			IMPORTANCE="$2"
			shift 2
			;;
		-j|--json)
			JSON=1
			shift
			;;
		-q|--quiet)
			QUIET=1
			shift
			;;
		*)
			break
			;;
	esac
done

# Parse command
case "$1" in
	status)
		cmd_status "$JSON"
		;;
	add)
		cmd_add "$2" "$3"
		;;
	get)
		cmd_get "$2"
		;;
	search)
		cmd_search "$2" "$3"
		;;
	list)
		cmd_list "$2" "$3"
		;;
	recent)
		cmd_recent "$2"
		;;
	important)
		cmd_important "$2"
		;;
	delete)
		cmd_delete "$2"
		;;
	cleanup)
		cmd_cleanup
		;;
	export)
		cmd_export "$2"
		;;
	import)
		cmd_import "$2"
		;;
	summarize)
		cmd_summarize "$2"
		;;
	context)
		cmd_context "$2"
		;;
	stats)
		cmd_stats
		;;
	help|--help|-h|"")
		usage
		;;
	*)
		echo "Unknown command: $1"
		usage
		exit 1
		;;
esac
