#!/bin/sh
# SecuBox OpenClaw manager - npm-based AI assistant
# Copyright (C) 2026 CyberMind.fr
#
# OpenClaw is a personal AI assistant that can manage emails, calendar,
# and integrate with chat platforms like Telegram, Discord, Slack.

CONFIG="openclaw"
INSTALL_DIR="/srv/openclaw"
PID_FILE="/var/run/openclaw.pid"

usage() {
	cat <<'EOF'
Usage: openclawctl <command>

Commands:
  install            Install OpenClaw via npm
  update             Update OpenClaw to latest version
  check              Run prerequisite checks
  status             Show service status
  logs               Show OpenClaw logs (use -f to follow)

Configuration:
  configure          Interactive setup (API keys, integrations)
  set-provider       Set LLM provider (anthropic/openai/ollama)
  set-api-key        Set LLM API key
  test-api           Test LLM API connection

Integrations:
  enable <name>      Enable integration (telegram/discord/slack/email)
  disable <name>     Disable integration
  list-integrations  List configured integrations

Service Control:
  service-run        Internal: run under procd
  service-stop       Stop service

API Endpoints (default port 3333):
  /api/chat          - Send message to AI
  /api/status        - Service status
  /api/integrations  - List active integrations

Configuration: /etc/config/openclaw
EOF
}

require_root() { [ "$(id -u)" -eq 0 ] || { echo "Root required" >&2; exit 1; }; }

log_info() { echo "[INFO] $*"; logger -t openclaw "$*"; }
log_warn() { echo "[WARN] $*" >&2; logger -t openclaw -p warning "$*"; }
log_error() { echo "[ERROR] $*" >&2; logger -t openclaw -p err "$*"; }

uci_get() { uci -q get ${CONFIG}.$1; }
uci_set() { uci set ${CONFIG}.$1="$2" && uci commit ${CONFIG}; }

# Load configuration
load_config() {
	port="$(uci_get main.port || echo 3333)"
	host="$(uci_get main.host || echo 0.0.0.0)"
	data_path="$(uci_get main.data_path || echo /srv/openclaw)"
	log_level="$(uci_get main.log_level || echo info)"

	# LLM settings
	llm_type="$(uci_get llm.type || echo anthropic)"
	api_key="$(uci_get llm.api_key || echo '')"
	ollama_url="$(uci_get llm.ollama_url || echo 'http://127.0.0.1:11434')"
	model="$(uci_get llm.model || echo 'claude-sonnet-4-20250514')"

	# Ensure paths exist
	[ -d "$data_path" ] || mkdir -p "$data_path"
}

# =============================================================================
# PREREQUISITES
# =============================================================================

has_node() {
	command -v node >/dev/null 2>&1
}

has_npm() {
	command -v npm >/dev/null 2>&1
}

get_node_version() {
	node --version 2>/dev/null | sed 's/^v//'
}

check_node_version() {
	local version=$(get_node_version)
	local major=$(echo "$version" | cut -d. -f1)
	[ "$major" -ge 18 ] 2>/dev/null
}

# =============================================================================
# INSTALLATION
# =============================================================================

cmd_install() {
	require_root
	load_config

	log_info "Installing OpenClaw..."

	# Check prerequisites
	if ! has_node; then
		log_error "Node.js not found. Install with: opkg install node"
		exit 1
	fi

	if ! check_node_version; then
		log_warn "Node.js 18+ recommended. Current: $(get_node_version)"
	fi

	if ! has_npm; then
		log_error "npm not found. Install with: opkg install node-npm"
		exit 1
	fi

	# Create install directory
	mkdir -p "$INSTALL_DIR"
	cd "$INSTALL_DIR" || exit 1

	# Initialize npm project if needed
	if [ ! -f "$INSTALL_DIR/package.json" ]; then
		log_info "Initializing npm project..."
		npm init -y >/dev/null 2>&1
	fi

	# Install OpenClaw
	log_info "Installing OpenClaw via npm..."
	log_info "This may take a few minutes..."

	if npm install -g openclaw 2>&1; then
		log_info "OpenClaw installed successfully!"
	else
		log_error "Failed to install OpenClaw"
		exit 1
	fi

	log_info ""
	log_info "Next steps:"
	log_info "  1. Configure API key: openclawctl set-api-key <your-key>"
	log_info "  2. Test connection: openclawctl test-api"
	log_info "  3. Enable service: uci set openclaw.main.enabled=1 && uci commit"
	log_info "  4. Start: /etc/init.d/openclaw start"
	log_info ""
	log_info "API will be available at: http://<router-ip>:$port"
}

cmd_update() {
	require_root
	log_info "Updating OpenClaw..."

	npm update -g openclaw

	if [ "$(uci_get main.enabled)" = "1" ]; then
		log_info "Restarting service..."
		/etc/init.d/openclaw restart
	fi
}

cmd_check() {
	load_config

	echo "=== OpenClaw Prerequisite Check ==="
	echo ""

	# Node.js
	if has_node; then
		local version=$(get_node_version)
		if check_node_version; then
			echo "[OK] Node.js: v$version"
		else
			echo "[WARN] Node.js: v$version (18+ recommended)"
		fi
	else
		echo "[FAIL] Node.js not found"
		echo "       Install: opkg install node"
	fi

	# npm
	if has_npm; then
		echo "[OK] npm: $(npm --version 2>/dev/null)"
	else
		echo "[FAIL] npm not found"
		echo "       Install: opkg install node-npm"
	fi
	echo ""

	# OpenClaw installation
	if command -v openclaw >/dev/null 2>&1; then
		echo "[OK] OpenClaw installed"
		openclaw --version 2>/dev/null || true
	else
		echo "[INFO] OpenClaw not installed"
		echo "       Run: openclawctl install"
	fi
	echo ""

	# LLM provider
	echo "=== LLM Configuration ==="
	echo "Provider: $llm_type"
	echo "Model: $model"
	if [ -n "$api_key" ] && [ "$api_key" != "" ]; then
		echo "API Key: ***configured***"
	else
		if [ "$llm_type" = "ollama" ]; then
			echo "API Key: (not required for Ollama)"
			echo "Ollama URL: $ollama_url"
		else
			echo "API Key: NOT SET"
			echo "       Configure with: openclawctl set-api-key <key>"
		fi
	fi
	echo ""

	# Check Ollama if configured
	if [ "$llm_type" = "ollama" ]; then
		if wget -q -O /dev/null "$ollama_url" 2>/dev/null; then
			echo "[OK] Ollama reachable at $ollama_url"
		else
			echo "[WARN] Ollama not responding at $ollama_url"
		fi
	fi

	# Storage
	local storage_avail=$(df -h "$data_path" 2>/dev/null | tail -1 | awk '{print $4}')
	echo "Storage available: $storage_avail (at $data_path)"
}

# =============================================================================
# CONFIGURATION
# =============================================================================

cmd_configure() {
	require_root
	load_config

	echo "=== OpenClaw Configuration ==="
	echo ""
	echo "Select LLM provider:"
	echo "  1) Anthropic (Claude)"
	echo "  2) OpenAI (GPT-4)"
	echo "  3) Ollama (Local)"
	echo ""
	printf "Choice [1-3]: "
	read choice

	case "$choice" in
		1)
			uci_set llm.type 'anthropic'
			uci_set llm.model 'claude-sonnet-4-20250514'
			echo "Selected: Anthropic Claude"
			echo ""
			printf "Enter Anthropic API key: "
			read -r api_key
			[ -n "$api_key" ] && uci_set llm.api_key "$api_key"
			;;
		2)
			uci_set llm.type 'openai'
			uci_set llm.model 'gpt-4o'
			echo "Selected: OpenAI GPT-4"
			echo ""
			printf "Enter OpenAI API key: "
			read -r api_key
			[ -n "$api_key" ] && uci_set llm.api_key "$api_key"
			;;
		3)
			uci_set llm.type 'ollama'
			uci_set llm.model 'mistral'
			echo "Selected: Ollama (Local)"
			echo ""
			printf "Enter Ollama URL [http://127.0.0.1:11434]: "
			read url
			[ -n "$url" ] && uci_set llm.ollama_url "$url"
			;;
		*)
			echo "Invalid choice"
			return 1
			;;
	esac

	echo ""
	echo "Configuration saved."
	echo "Test with: openclawctl test-api"
}

cmd_set_provider() {
	require_root
	local provider="$1"

	case "$provider" in
		anthropic)
			uci_set llm.type 'anthropic'
			uci_set llm.model 'claude-sonnet-4-20250514'
			echo "Provider set to Anthropic"
			;;
		openai)
			uci_set llm.type 'openai'
			uci_set llm.model 'gpt-4o'
			echo "Provider set to OpenAI"
			;;
		ollama)
			uci_set llm.type 'ollama'
			uci_set llm.model 'mistral'
			echo "Provider set to Ollama"
			;;
		*)
			echo "Usage: openclawctl set-provider <anthropic|openai|ollama>"
			return 1
			;;
	esac
}

cmd_set_api_key() {
	require_root
	local key="$1"

	if [ -z "$key" ]; then
		echo "Usage: openclawctl set-api-key <api-key>"
		return 1
	fi

	uci_set llm.api_key "$key"
	echo "API key configured"
}

cmd_test_api() {
	load_config

	echo "Testing LLM API connection..."
	echo "Provider: $llm_type"
	echo "Model: $model"
	echo ""

	case "$llm_type" in
		anthropic)
			if [ -z "$api_key" ]; then
				log_error "API key not configured"
				return 1
			fi
			# Test Anthropic API
			local response=$(wget -q -O - \
				--header="x-api-key: $api_key" \
				--header="anthropic-version: 2023-06-01" \
				--header="content-type: application/json" \
				--post-data='{"model":"'"$model"'","max_tokens":10,"messages":[{"role":"user","content":"Hi"}]}' \
				"https://api.anthropic.com/v1/messages" 2>&1)

			if echo "$response" | grep -q '"content"'; then
				echo "[OK] Anthropic API working"
			else
				log_error "API test failed: $response"
				return 1
			fi
			;;
		openai)
			if [ -z "$api_key" ]; then
				log_error "API key not configured"
				return 1
			fi
			local response=$(wget -q -O - \
				--header="Authorization: Bearer $api_key" \
				--header="content-type: application/json" \
				--post-data='{"model":"'"$model"'","max_tokens":10,"messages":[{"role":"user","content":"Hi"}]}' \
				"https://api.openai.com/v1/chat/completions" 2>&1)

			if echo "$response" | grep -q '"choices"'; then
				echo "[OK] OpenAI API working"
			else
				log_error "API test failed: $response"
				return 1
			fi
			;;
		ollama)
			if wget -q -O /dev/null "$ollama_url" 2>/dev/null; then
				echo "[OK] Ollama reachable"
				# Check if model exists
				local models=$(wget -q -O - "$ollama_url/api/tags" 2>/dev/null)
				if echo "$models" | grep -q "$model"; then
					echo "[OK] Model '$model' available"
				else
					log_warn "Model '$model' not found. Pull with: ollamactl pull $model"
				fi
			else
				log_error "Ollama not reachable at $ollama_url"
				return 1
			fi
			;;
	esac
}

# =============================================================================
# INTEGRATIONS
# =============================================================================

cmd_list_integrations() {
	load_config

	echo "=== OpenClaw Integrations ==="
	echo ""

	for int in telegram discord slack email calendar; do
		local enabled=$(uci_get $int.enabled || echo 0)
		if [ "$enabled" = "1" ]; then
			echo "  [ON]  $int"
		else
			echo "  [OFF] $int"
		fi
	done
	echo ""
	echo "Enable with: openclawctl enable <integration>"
}

cmd_enable_integration() {
	require_root
	local name="$1"

	case "$name" in
		telegram|discord|slack|email|calendar)
			uci_set $name.enabled '1'
			echo "Enabled: $name"
			echo "Configure tokens/credentials in /etc/config/openclaw"
			;;
		*)
			echo "Unknown integration: $name"
			echo "Available: telegram, discord, slack, email, calendar"
			return 1
			;;
	esac
}

cmd_disable_integration() {
	require_root
	local name="$1"

	case "$name" in
		telegram|discord|slack|email|calendar)
			uci_set $name.enabled '0'
			echo "Disabled: $name"
			;;
		*)
			echo "Unknown integration: $name"
			return 1
			;;
	esac
}

# =============================================================================
# SERVICE CONTROL
# =============================================================================

cmd_status() {
	load_config

	echo "=== OpenClaw Status ==="
	echo ""

	# Check if installed
	if command -v openclaw >/dev/null 2>&1; then
		echo "Installation: INSTALLED"
		openclaw --version 2>/dev/null || true
	else
		echo "Installation: NOT INSTALLED"
		echo "Run: openclawctl install"
		return 0
	fi
	echo ""

	# Check if running
	if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
		echo "Service: RUNNING (PID: $(cat "$PID_FILE"))"
	else
		if pgrep -f "openclaw" >/dev/null 2>&1; then
			echo "Service: RUNNING"
		else
			echo "Service: STOPPED"
		fi
	fi
	echo ""

	# API health check
	if wget -q -O /dev/null "http://127.0.0.1:$port/api/status" 2>/dev/null; then
		echo "API: HEALTHY (port $port)"
	else
		echo "API: NOT RESPONDING"
	fi
	echo ""

	# Configuration
	echo "=== Configuration ==="
	echo "LLM Provider: $llm_type"
	echo "Model: $model"
	echo "Port: $port"
	echo "Data: $data_path"
}

cmd_logs() {
	if [ "$1" = "-f" ]; then
		logread -f -e openclaw
	else
		logread -e openclaw | tail -100
	fi
}

cmd_service_run() {
	require_root
	load_config

	# Build environment
	export OPENCLAW_PORT="$port"
	export OPENCLAW_HOST="$host"
	export OPENCLAW_DATA_DIR="$data_path"
	export OPENCLAW_LOG_LEVEL="$log_level"

	# LLM config
	case "$llm_type" in
		anthropic)
			export ANTHROPIC_API_KEY="$api_key"
			export OPENCLAW_MODEL="$model"
			;;
		openai)
			export OPENAI_API_KEY="$api_key"
			export OPENCLAW_MODEL="$model"
			;;
		ollama)
			export OLLAMA_HOST="$ollama_url"
			export OPENCLAW_MODEL="$model"
			;;
	esac

	# Store PID
	echo $$ > "$PID_FILE"

	# Run OpenClaw
	log_info "Starting OpenClaw on $host:$port"
	exec openclaw serve --port "$port" --host "$host"
}

cmd_service_stop() {
	require_root

	if [ -f "$PID_FILE" ]; then
		local pid=$(cat "$PID_FILE")
		if kill -0 "$pid" 2>/dev/null; then
			log_info "Stopping OpenClaw (PID: $pid)"
			kill "$pid"
		fi
		rm -f "$PID_FILE"
	fi

	# Also kill any stray processes
	pkill -f "openclaw serve" 2>/dev/null || true
}

# Main Entry Point
case "${1:-}" in
	install) shift; cmd_install "$@" ;;
	update) shift; cmd_update "$@" ;;
	check) shift; cmd_check "$@" ;;
	status) shift; cmd_status "$@" ;;
	logs) shift; cmd_logs "$@" ;;
	configure) shift; cmd_configure "$@" ;;
	set-provider) shift; cmd_set_provider "$@" ;;
	set-api-key) shift; cmd_set_api_key "$@" ;;
	test-api) shift; cmd_test_api "$@" ;;
	list-integrations) shift; cmd_list_integrations "$@" ;;
	enable) shift; cmd_enable_integration "$@" ;;
	disable) shift; cmd_disable_integration "$@" ;;
	service-run) shift; cmd_service_run "$@" ;;
	service-stop) shift; cmd_service_stop "$@" ;;
	help|--help|-h|'') usage ;;
	*) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;;
esac
