#!/bin/sh
# Jitsi Meet Control Script for SecuBox
# Manages Jitsi Meet Docker deployment

VERSION="1.0.0"
JITSI_DIR="/srv/jitsi"
CONFIG_DIR="$JITSI_DIR/.jitsi-meet-cfg"
TEMPLATE_DIR="/usr/share/jitsi"
ENV_FILE="$JITSI_DIR/.env"
COMPOSE_FILE="$JITSI_DIR/docker-compose.yml"

# Jitsi Docker image versions
JITSI_IMAGE_VERSION="stable-9location1"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

log() { echo -e "${GREEN}[JITSI]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }

# ============================================================================
# Configuration Generation
# ============================================================================

generate_secret() {
	openssl rand -hex 16 2>/dev/null || head -c 32 /dev/urandom | md5sum | cut -d' ' -f1
}

generate_config() {
	log "Generating Jitsi configuration..."

	mkdir -p "$JITSI_DIR"
	mkdir -p "$CONFIG_DIR"/{web,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}

	# Read UCI configuration
	local domain=$(uci -q get jitsi.main.domain || echo "meet.secubox.local")
	local public_url=$(uci -q get jitsi.main.public_url)
	[ -z "$public_url" ] && public_url="https://$domain"
	local timezone=$(uci -q get jitsi.main.timezone || echo "UTC")
	local letsencrypt=$(uci -q get jitsi.main.letsencrypt || echo "0")
	local le_email=$(uci -q get jitsi.main.letsencrypt_email)

	# Web config
	local web_port=$(uci -q get jitsi.web.port || echo "8443")
	local enable_guests=$(uci -q get jitsi.web.enable_guests || echo "1")
	local enable_auth=$(uci -q get jitsi.web.enable_auth || echo "0")
	local default_lang=$(uci -q get jitsi.web.default_language || echo "en")

	# JVB config
	local jvb_port=$(uci -q get jitsi.jvb.port || echo "10000")
	local jvb_tcp=$(uci -q get jitsi.jvb.enable_tcp_fallback || echo "0")
	local jvb_tcp_port=$(uci -q get jitsi.jvb.tcp_port || echo "4443")
	local stun_servers=$(uci -q get jitsi.jvb.stun_servers || echo "meet-jit-si-turnrelay.jitsi.net:443")

	# Security
	local jwt_enabled=$(uci -q get jitsi.security.jwt_enabled || echo "0")
	local jwt_app_id=$(uci -q get jitsi.security.jwt_app_id)
	local jwt_secret=$(uci -q get jitsi.security.jwt_app_secret)
	local lobby=$(uci -q get jitsi.security.lobby_enabled || echo "1")

	# TURN
	local turn_enabled=$(uci -q get jitsi.turn.enabled || echo "0")
	local turn_server=$(uci -q get jitsi.turn.server)
	local turn_user=$(uci -q get jitsi.turn.username)
	local turn_pass=$(uci -q get jitsi.turn.password)

	# Generate secrets if not already stored
	local jicofo_secret=$(uci -q get jitsi.secrets.jicofo_component_secret)
	local jicofo_auth_pass=$(uci -q get jitsi.secrets.jicofo_auth_password)
	local jvb_auth_pass=$(uci -q get jitsi.secrets.jvb_auth_password)

	if [ -z "$jicofo_secret" ]; then
		jicofo_secret=$(generate_secret)
		uci -q set jitsi.secrets=jitsi
		uci -q set jitsi.secrets.jicofo_component_secret="$jicofo_secret"
	fi
	if [ -z "$jicofo_auth_pass" ]; then
		jicofo_auth_pass=$(generate_secret)
		uci -q set jitsi.secrets.jicofo_auth_password="$jicofo_auth_pass"
	fi
	if [ -z "$jvb_auth_pass" ]; then
		jvb_auth_pass=$(generate_secret)
		uci -q set jitsi.secrets.jvb_auth_password="$jvb_auth_pass"
		uci commit jitsi
	fi

	# Determine auth type
	local auth_type="internal"
	[ "$enable_auth" = "1" ] && auth_type="internal_hashed"
	[ "$jwt_enabled" = "1" ] && auth_type="jwt"

	# Write .env file
	cat > "$ENV_FILE" << EOF
# Jitsi Meet Configuration
# Generated by SecuBox jitsctl v$VERSION
# $(date)

# Core settings
CONFIG=$CONFIG_DIR
HTTP_PORT=8000
HTTPS_PORT=$web_port
TZ=$timezone

# Domain settings
PUBLIC_URL=$public_url
XMPP_DOMAIN=$domain
XMPP_SERVER=xmpp.$domain
JVB_BREWERY_MUC=jvbbrewery
XMPP_AUTH_DOMAIN=auth.$domain
XMPP_GUEST_DOMAIN=guest.$domain
XMPP_MUC_DOMAIN=muc.$domain
XMPP_INTERNAL_MUC_DOMAIN=internal-muc.$domain
XMPP_MODULES=
XMPP_MUC_MODULES=
XMPP_INTERNAL_MUC_MODULES=

# Authentication
ENABLE_AUTH=$enable_auth
ENABLE_GUESTS=$enable_guests
AUTH_TYPE=$auth_type

# JWT (if enabled)
EOF

	if [ "$jwt_enabled" = "1" ]; then
		cat >> "$ENV_FILE" << EOF
JWT_APP_ID=$jwt_app_id
JWT_APP_SECRET=$jwt_secret
JWT_ACCEPTED_ISSUERS=$jwt_app_id
JWT_ACCEPTED_AUDIENCES=$jwt_app_id
EOF
	fi

	cat >> "$ENV_FILE" << EOF

# XMPP secrets
JICOFO_COMPONENT_SECRET=$jicofo_secret
JICOFO_AUTH_USER=focus
JICOFO_AUTH_PASSWORD=$jicofo_auth_pass
JVB_AUTH_USER=jvb
JVB_AUTH_PASSWORD=$jvb_auth_pass

# JVB settings
JVB_PORT=$jvb_port
JVB_STUN_SERVERS=$stun_servers
JVB_TCP_HARVESTER_DISABLED=$([ "$jvb_tcp" = "1" ] && echo "false" || echo "true")
JVB_TCP_PORT=$jvb_tcp_port

# Features
ENABLE_LOBBY=$lobby
ENABLE_BREAKOUT_ROOMS=1
ENABLE_PREJOIN_PAGE=1
ENABLE_WELCOME_PAGE=1
ENABLE_CLOSE_PAGE=0
ENABLE_NOISY_MIC_DETECTION=1
ENABLE_TALK_WHILE_MUTED=1
ENABLE_REACTIONS=1

# UI settings
DEFAULT_LANGUAGE=$default_lang
DISABLE_AUDIO_LEVELS=0
DISABLE_POLLS=0
ENABLE_CALENDAR=0
EOF

	# Add TURN config if enabled
	if [ "$turn_enabled" = "1" ] && [ -n "$turn_server" ]; then
		cat >> "$ENV_FILE" << EOF

# TURN server
TURN_CREDENTIALS=$turn_user
TURN_SECRET=$turn_pass
TURN_HOST=$turn_server
TURN_PORT=443
TURNS_HOST=$turn_server
TURNS_PORT=443
EOF
	fi

	# Add Let's Encrypt config
	if [ "$letsencrypt" = "1" ] && [ -n "$le_email" ]; then
		cat >> "$ENV_FILE" << EOF

# Let's Encrypt
ENABLE_LETSENCRYPT=1
LETSENCRYPT_DOMAIN=$domain
LETSENCRYPT_EMAIL=$le_email
LETSENCRYPT_USE_STAGING=0
EOF
	fi

	# Copy docker-compose.yml
	cp "$TEMPLATE_DIR/docker-compose.yml" "$COMPOSE_FILE"

	log "Configuration generated at $ENV_FILE"
}

# ============================================================================
# Installation
# ============================================================================

install_jitsi() {
	log "Installing Jitsi Meet..."

	# Check Docker
	if ! command -v docker >/dev/null 2>&1; then
		error "Docker is required. Install with: opkg install docker docker-compose"
		return 1
	fi

	# Create directories
	mkdir -p "$JITSI_DIR"
	mkdir -p "$CONFIG_DIR"

	# Generate configuration
	generate_config

	# Pull images
	log "Pulling Jitsi Docker images (this may take a while)..."
	cd "$JITSI_DIR"
	docker-compose pull

	# Configure HAProxy if available
	if [ -x /usr/sbin/haproxyctl ]; then
		configure_haproxy
	fi

	# Configure firewall
	configure_firewall

	# Register with mesh
	register_mesh_service

	log "Jitsi Meet installed successfully!"
	echo ""
	echo "Next steps:"
	echo "  1. Set your domain: uci set jitsi.main.domain='meet.example.com'"
	echo "  2. Commit changes:  uci commit jitsi"
	echo "  3. Regenerate:      jitsctl generate-config"
	echo "  4. Enable service:  uci set jitsi.main.enabled=1 && uci commit jitsi"
	echo "  5. Start:           /etc/init.d/jitsi start"
	echo ""
}

# ============================================================================
# HAProxy Integration
# ============================================================================

configure_haproxy() {
	log "Configuring HAProxy for Jitsi..."

	local domain=$(uci -q get jitsi.main.domain || echo "meet.secubox.local")
	local web_port=$(uci -q get jitsi.web.port || echo "8443")

	# Check if vhost already exists
	local existing=$(uci show haproxy 2>/dev/null | grep "\.domain='$domain'" | head -1)
	if [ -n "$existing" ]; then
		warn "HAProxy vhost for $domain already exists"
		return 0
	fi

	# Add backend
	uci -q add haproxy backend
	uci -q set haproxy.@backend[-1].name='jitsi_web'
	uci -q set haproxy.@backend[-1].mode='http'
	uci -q add_list haproxy.@backend[-1].server="jitsi 127.0.0.1:$web_port check"

	# Add vhost
	uci -q add haproxy vhost
	uci -q set haproxy.@vhost[-1].enabled='1'
	uci -q set haproxy.@vhost[-1].domain="$domain"
	uci -q set haproxy.@vhost[-1].backend='jitsi_web'
	uci -q set haproxy.@vhost[-1].ssl='1'
	uci -q set haproxy.@vhost[-1].ssl_redirect='1'
	uci -q set haproxy.@vhost[-1].websocket='1'

	uci commit haproxy

	# Reload HAProxy
	/etc/init.d/haproxy reload 2>/dev/null

	log "HAProxy configured for $domain"
}

# ============================================================================
# Firewall
# ============================================================================

configure_firewall() {
	log "Configuring firewall..."

	local jvb_port=$(uci -q get jitsi.jvb.port || echo "10000")
	local jvb_tcp_port=$(uci -q get jitsi.jvb.tcp_port || echo "4443")

	# JVB UDP port (required for video)
	if ! uci show firewall 2>/dev/null | grep -q "Jitsi-JVB"; then
		uci add firewall rule
		uci set firewall.@rule[-1].name='Jitsi-JVB'
		uci set firewall.@rule[-1].src='wan'
		uci set firewall.@rule[-1].dest_port="$jvb_port"
		uci set firewall.@rule[-1].proto='udp'
		uci set firewall.@rule[-1].target='ACCEPT'
		uci set firewall.@rule[-1].enabled='1'
	fi

	# JVB TCP fallback port
	local jvb_tcp=$(uci -q get jitsi.jvb.enable_tcp_fallback || echo "0")
	if [ "$jvb_tcp" = "1" ]; then
		if ! uci show firewall 2>/dev/null | grep -q "Jitsi-JVB-TCP"; then
			uci add firewall rule
			uci set firewall.@rule[-1].name='Jitsi-JVB-TCP'
			uci set firewall.@rule[-1].src='wan'
			uci set firewall.@rule[-1].dest_port="$jvb_tcp_port"
			uci set firewall.@rule[-1].proto='tcp'
			uci set firewall.@rule[-1].target='ACCEPT'
			uci set firewall.@rule[-1].enabled='1'
		fi
	fi

	uci commit firewall
	/etc/init.d/firewall reload 2>/dev/null

	log "Firewall configured"
}

# ============================================================================
# Mesh Integration
# ============================================================================

register_mesh_service() {
	local mesh_enabled=$(uci -q get jitsi.mesh.enabled || echo "0")
	[ "$mesh_enabled" != "1" ] && return 0

	local domain=$(uci -q get jitsi.main.domain)
	local web_port=$(uci -q get jitsi.web.port || echo "8443")

	# Register with P2P daemon
	if [ -x /usr/sbin/secubox-p2p ]; then
		/usr/sbin/secubox-p2p register-service jitsi-meet "$web_port" 2>/dev/null
		log "Registered Jitsi with mesh network"
	fi

	# Add DNS entry if DNS federation enabled
	local dns_enabled=$(uci -q get secubox-p2p.dns.enabled || echo "0")
	if [ "$dns_enabled" = "1" ]; then
		local dns_domain=$(uci -q get secubox-p2p.dns.base_domain || echo "mesh.local")
		local hostname=$(echo "$domain" | cut -d'.' -f1)
		log "Mesh DNS: $hostname.$dns_domain"
	fi
}

# ============================================================================
# User Management
# ============================================================================

add_user() {
	local username="$1"
	local password="$2"

	if [ -z "$username" ] || [ -z "$password" ]; then
		echo "Usage: jitsctl add-user <username> <password>"
		return 1
	fi

	local domain=$(uci -q get jitsi.main.domain)

	log "Adding user: $username"

	docker exec jitsi-prosody prosodyctl register "$username" "$domain" "$password"

	if [ $? -eq 0 ]; then
		log "User $username added successfully"
	else
		error "Failed to add user $username"
		return 1
	fi
}

remove_user() {
	local username="$1"

	if [ -z "$username" ]; then
		echo "Usage: jitsctl remove-user <username>"
		return 1
	fi

	local domain=$(uci -q get jitsi.main.domain)

	log "Removing user: $username"

	docker exec jitsi-prosody prosodyctl unregister "$username" "$domain"

	if [ $? -eq 0 ]; then
		log "User $username removed"
	else
		error "Failed to remove user $username"
		return 1
	fi
}

list_users() {
	local domain=$(uci -q get jitsi.main.domain)

	echo "Registered users for $domain:"
	docker exec jitsi-prosody ls -1 /config/data/"$domain"/accounts/ 2>/dev/null | sed 's/\.dat$//'
}

# ============================================================================
# Status & Logs
# ============================================================================

show_status() {
	echo ""
	echo "========================================"
	echo "  Jitsi Meet Status v$VERSION"
	echo "========================================"
	echo ""

	local enabled=$(uci -q get jitsi.main.enabled)
	local domain=$(uci -q get jitsi.main.domain)
	local public_url=$(uci -q get jitsi.main.public_url)
	[ -z "$public_url" ] && public_url="https://$domain"

	echo "Configuration:"
	echo "  Enabled:    $([ "$enabled" = "1" ] && echo -e "${GREEN}Yes${NC}" || echo -e "${RED}No${NC}")"
	echo "  Domain:     $domain"
	echo "  Public URL: $public_url"
	echo ""

	if ! command -v docker >/dev/null 2>&1; then
		echo -e "Docker:       ${RED}Not installed${NC}"
		return
	fi

	echo "Containers:"
	for container in jitsi-web jitsi-prosody jitsi-jicofo jitsi-jvb; do
		local state=$(docker inspect -f '{{.State.Status}}' "$container" 2>/dev/null)
		if [ "$state" = "running" ]; then
			echo -e "  $container: ${GREEN}Running${NC}"
		elif [ -n "$state" ]; then
			echo -e "  $container: ${YELLOW}$state${NC}"
		else
			echo -e "  $container: ${RED}Not found${NC}"
		fi
	done
	echo ""

	# Show ports
	local jvb_port=$(uci -q get jitsi.jvb.port || echo "10000")
	local web_port=$(uci -q get jitsi.web.port || echo "8443")
	echo "Ports:"
	echo "  Web:        $web_port/tcp"
	echo "  JVB Media:  $jvb_port/udp"
	echo ""

	# Show active conferences (if available)
	local stats=$(docker exec jitsi-jvb curl -s http://localhost:8080/colibri/stats 2>/dev/null)
	if [ -n "$stats" ]; then
		local conferences=$(echo "$stats" | jsonfilter -e '@.conferences' 2>/dev/null || echo "0")
		local participants=$(echo "$stats" | jsonfilter -e '@.participants' 2>/dev/null || echo "0")
		echo "Active:"
		echo "  Conferences:  $conferences"
		echo "  Participants: $participants"
		echo ""
	fi
}

show_logs() {
	local service="$1"
	local lines="${2:-50}"

	cd "$JITSI_DIR"

	case "$service" in
		web|prosody|jicofo|jvb)
			docker-compose logs --tail="$lines" "$service"
			;;
		all|"")
			docker-compose logs --tail="$lines"
			;;
		*)
			echo "Usage: jitsctl logs [web|prosody|jicofo|jvb|all] [lines]"
			;;
	esac
}

shell() {
	local container="${1:-jitsi-prosody}"

	log "Connecting to $container..."
	docker exec -it "$container" /bin/bash 2>/dev/null || docker exec -it "$container" /bin/sh
}

# ============================================================================
# Upgrade
# ============================================================================

upgrade() {
	log "Upgrading Jitsi Meet..."

	cd "$JITSI_DIR"

	# Pull latest images
	docker-compose pull

	# Restart with new images
	docker-compose down
	docker-compose up -d

	# Cleanup old images
	docker image prune -f

	log "Jitsi Meet upgraded"
}

# ============================================================================
# Backup / Restore
# ============================================================================

backup() {
	local backup_file="${1:-/tmp/jitsi-backup-$(date +%Y%m%d-%H%M%S).tar.gz}"

	log "Creating backup..."

	tar -czf "$backup_file" \
		-C / \
		etc/config/jitsi \
		"$CONFIG_DIR" \
		"$ENV_FILE" \
		2>/dev/null

	if [ -f "$backup_file" ]; then
		local size=$(ls -lh "$backup_file" | awk '{print $5}')
		log "Backup created: $backup_file ($size)"
	else
		error "Backup failed"
		return 1
	fi
}

restore() {
	local backup_file="$1"

	if [ -z "$backup_file" ] || [ ! -f "$backup_file" ]; then
		echo "Usage: jitsctl restore <backup_file>"
		return 1
	fi

	log "Restoring from $backup_file..."

	# Stop service
	/etc/init.d/jitsi stop 2>/dev/null

	# Extract backup
	tar -xzf "$backup_file" -C /

	# Restart
	/etc/init.d/jitsi start

	log "Restore complete"
}

# ============================================================================
# Main
# ============================================================================

show_help() {
	cat << EOF
Jitsi Meet Control v$VERSION

Usage: jitsctl <command> [options]

Commands:
  install           Install Jitsi Meet Docker stack
  generate-config   Generate/update configuration from UCI
  status            Show service status
  logs [svc] [n]    Show container logs
  shell [container] Access container shell

  start             Start all containers
  stop              Stop all containers
  restart           Restart all containers
  upgrade           Upgrade to latest images

  add-user <u> <p>  Add authenticated user
  remove-user <u>   Remove user
  list-users        List registered users

  backup [file]     Create configuration backup
  restore <file>    Restore from backup

  configure-haproxy Add HAProxy vhost
  configure-fw      Configure firewall rules

Examples:
  jitsctl install
  jitsctl status
  jitsctl logs jvb 100
  jitsctl add-user admin secretpassword

EOF
}

case "$1" in
	install)
		install_jitsi
		;;
	generate-config)
		generate_config
		;;
	status)
		show_status
		;;
	logs)
		show_logs "$2" "$3"
		;;
	shell)
		shell "$2"
		;;
	start)
		cd "$JITSI_DIR" && docker-compose up -d
		;;
	stop)
		cd "$JITSI_DIR" && docker-compose down
		;;
	restart)
		cd "$JITSI_DIR" && docker-compose restart
		;;
	upgrade)
		upgrade
		;;
	add-user)
		add_user "$2" "$3"
		;;
	remove-user)
		remove_user "$2"
		;;
	list-users)
		list_users
		;;
	backup)
		backup "$2"
		;;
	restore)
		restore "$2"
		;;
	configure-haproxy)
		configure_haproxy
		;;
	configure-fw)
		configure_firewall
		;;
	-h|--help|help)
		show_help
		;;
	*)
		show_help
		exit 1
		;;
esac

exit 0
