#!/bin/sh
# SecuBox Mail Server Controller

VERSION="1.0.0"
CONFIG="mailserver"
LIB_DIR="/usr/lib/mailserver"

# Load libraries
. "$LIB_DIR/container.sh"
. "$LIB_DIR/users.sh"
. "$LIB_DIR/mesh.sh"

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

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

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

# ============================================================================
# Install / Setup
# ============================================================================

cmd_install() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"

	log "Installing mail server..."

	# Create container
	container_create "$container" "$data_path"
	local rc=$?

	[ $rc -ne 0 ] && return $rc

	# Start container
	log "Starting container..."
	lxc-start -n "$container"
	sleep 5

	# Run setup
	log "Installing mail packages..."
	lxc-attach -n "$container" -- /root/setup.sh

	log "Installation complete!"
	echo ""
	echo "Next steps:"
	echo "  1. Configure domain: uci set mailserver.main.domain='yourdomain.com'"
	echo "  2. Set up DNS:       dnsctl mail-setup"
	echo "  3. Add SSL cert:     mailctl ssl-setup"
	echo "  4. Add users:        mailctl user-add user@yourdomain.com"
	echo "  5. Enable:           uci set mailserver.main.enabled=1 && uci commit"
}

cmd_uninstall() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"

	warn "This will remove the mail server container and all data!"
	echo "Continue? (yes/no)"
	read confirm
	[ "$confirm" != "yes" ] && { echo "Aborted"; return 1; }

	log "Stopping container..."
	lxc-stop -n "$container" 2>/dev/null

	log "Removing container..."
	rm -rf "/srv/lxc/$container"

	log "Mail server removed. Data in $(uci_get main.data_path) preserved."
}

# ============================================================================
# Service Control
# ============================================================================

cmd_start() {
	/etc/init.d/mailserver start
}

cmd_stop() {
	/etc/init.d/mailserver stop
}

cmd_restart() {
	/etc/init.d/mailserver stop
	sleep 2
	/etc/init.d/mailserver start
}

cmd_status() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local domain=$(uci_get main.domain)
	local hostname=$(uci_get main.hostname)

	echo ""
	echo "========================================"
	echo "  SecuBox Mail Server v$VERSION"
	echo "========================================"
	echo ""

	# Container status
	local state="stopped"
	lxc-info -n "$container" 2>/dev/null | grep -q "RUNNING" && state="running"
	echo "  Container:   $container ($state)"
	echo "  Domain:      ${domain:-not set}"
	echo "  Hostname:    ${hostname:-mail}.${domain:-example.com}"
	echo ""

	# Port status - check inside container
	echo "  Ports:"
	local ports="25 587 465 993 995"
	local container_ports=""
	if [ "$state" = "running" ]; then
		container_ports=$(lxc-attach -n "$container" -- netstat -tln 2>/dev/null)
	fi
	for port in $ports; do
		if echo "$container_ports" | grep -q ":$port "; then
			echo -e "    $port: ${GREEN}listening${NC}"
		else
			echo -e "    $port: ${RED}closed${NC}"
		fi
	done
	echo ""

	# User count
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"
	local user_count=$(wc -l < "$data_path/config/users" 2>/dev/null || echo "0")
	echo "  Users:       $user_count"

	# Storage
	local storage=$(du -sh "$data_path" 2>/dev/null | awk '{print $1}')
	echo "  Storage:     ${storage:-0}"
	echo ""
}

# ============================================================================
# User Commands
# ============================================================================

cmd_user() {
	local action="$1"
	shift

	case "$action" in
		add)     user_add "$@" ;;
		del)     user_del "$@" ;;
		list)    user_list ;;
		passwd)  user_passwd "$@" ;;
		*)
			echo "User commands:"
			echo "  user add <email@domain>  Add mail user"
			echo "  user del <email@domain>  Delete mail user"
			echo "  user list                List all users"
			echo "  user passwd <email>      Change password"
			;;
	esac
}

cmd_alias() {
	local action="$1"
	shift

	case "$action" in
		add)   alias_add "$@" ;;
		del)   alias_del "$@" ;;
		list)  alias_list ;;
		*)
			echo "Alias commands:"
			echo "  alias add <alias> <target>  Add email alias"
			echo "  alias del <alias>           Delete email alias"
			echo "  alias list                  List aliases"
			;;
	esac
}

# ============================================================================
# SSL Certificate
# ============================================================================

cmd_ssl_setup() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local domain=$(uci_get main.domain)
	local hostname=$(uci_get main.hostname)
	hostname="${hostname:-mail}"
	local fqdn="${hostname}.${domain}"

	log "Setting up SSL for $fqdn..."

	# Check if acme.sh available
	if ! command -v acme.sh >/dev/null 2>&1; then
		error "acme.sh not installed. Install with: opkg install acme acme-dnsapi"
		return 1
	fi

	# Use DNS-01 via dnsctl
	log "Requesting certificate via DNS-01..."
	dnsctl acme-dns01 "$fqdn"

	local cert_dir="/root/.acme.sh/${fqdn}"
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"

	if [ -f "$cert_dir/fullchain.cer" ]; then
		cp "$cert_dir/fullchain.cer" "$data_path/ssl/fullchain.pem"
		cp "$cert_dir/${fqdn}.key" "$data_path/ssl/privkey.pem"
		chmod 600 "$data_path/ssl/"*.pem

		log "SSL certificates installed to $data_path/ssl/"
		log "Restarting mail services..."
		cmd_restart
	else
		error "Certificate generation failed"
		return 1
	fi
}

cmd_ssl_status() {
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"

	if [ -f "$data_path/ssl/fullchain.pem" ]; then
		echo "SSL Certificate:"
		openssl x509 -in "$data_path/ssl/fullchain.pem" -noout -subject -dates 2>/dev/null | sed 's/^/  /'
	else
		echo "No SSL certificate installed"
	fi
}

# ============================================================================
# DNS Integration
# ============================================================================

cmd_dns_setup() {
	local hostname=$(uci_get main.hostname)
	hostname="${hostname:-mail}"

	log "Setting up DNS records..."
	dnsctl mail-setup "$hostname"
}

# ============================================================================
# Mesh Commands
# ============================================================================

cmd_mesh() {
	local action="$1"
	shift

	case "$action" in
		backup)     mesh_backup ;;
		restore)    mesh_restore "$@" ;;
		sync)       mesh_sync "$@" ;;
		add-peer)   mesh_add_peer "$@" ;;
		peers)      mesh_list_peers ;;
		enable)
			uci set $CONFIG.mesh.enabled=1
			uci commit $CONFIG
			log "Mesh sync enabled"
			;;
		disable)
			uci set $CONFIG.mesh.enabled=0
			uci commit $CONFIG
			log "Mesh sync disabled"
			;;
		*)
			echo "Mesh commands:"
			echo "  mesh backup              Create backup for mesh"
			echo "  mesh restore <file>      Restore from backup"
			echo "  mesh sync [push|pull]    Sync with peers"
			echo "  mesh add-peer <id>       Add mesh peer"
			echo "  mesh peers               List mesh peers"
			echo "  mesh enable              Enable mesh sync"
			echo "  mesh disable             Disable mesh sync"
			;;
	esac
}

# ============================================================================
# Fix / Repair
# ============================================================================

cmd_fix_postfix() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local domain=$(uci_get main.domain)

	log "Fixing Postfix configuration..."

	# Fix LMDB maps (Alpine doesn't support hash maps)
	lxc-attach -n "$container" -- sh -c "
		# Use LMDB instead of hash (Alpine Postfix)
		postconf -e 'virtual_mailbox_maps = lmdb:/etc/postfix/vmailbox'
		postconf -e 'virtual_alias_maps = lmdb:/etc/postfix/virtual'
		postconf -e 'virtual_mailbox_domains = /etc/postfix/vdomains'

		# Don't include domain in mydestination (conflicts with virtual)
		postconf -e 'mydestination = \\\$myhostname, localhost.\\\$mydomain, localhost'

		# Ensure vdomains file exists
		echo '$domain' > /etc/postfix/vdomains

		# Regenerate LMDB databases
		[ -f /etc/postfix/vmailbox ] && postmap lmdb:/etc/postfix/vmailbox
		[ -f /etc/postfix/virtual ] && postmap lmdb:/etc/postfix/virtual

		# Fix Postfix chroot DNS resolution
		mkdir -p /var/spool/postfix/etc
		cp /etc/resolv.conf /var/spool/postfix/etc/

		# Reload Postfix
		postfix reload
	"

	log "Postfix configuration fixed"
	log "If you still see errors, restart the container: mailctl restart"
}

cmd_fix_ports() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"

	log "Enabling submission (587), smtps (465), and POP3S (995) ports..."

	lxc-attach -n "$container" -- sh -c '
		# Enable submission port (587) in master.cf
		if ! grep -q "^submission " /etc/postfix/master.cf; then
			echo "submission inet n       -       n       -       -       smtpd" >> /etc/postfix/master.cf
			echo "  -o syslog_name=postfix/submission" >> /etc/postfix/master.cf
			echo "  -o smtpd_tls_security_level=encrypt" >> /etc/postfix/master.cf
			echo "  -o smtpd_sasl_auth_enable=yes" >> /etc/postfix/master.cf
			echo "  -o smtpd_tls_auth_only=yes" >> /etc/postfix/master.cf
			echo "  -o smtpd_reject_unlisted_recipient=no" >> /etc/postfix/master.cf
			echo "  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject" >> /etc/postfix/master.cf
			echo "  -o milter_macro_daemon_name=ORIGINATING" >> /etc/postfix/master.cf
		fi

		# Enable smtps port (465) in master.cf
		if ! grep -q "^smtps " /etc/postfix/master.cf; then
			echo "smtps     inet  n       -       n       -       -       smtpd" >> /etc/postfix/master.cf
			echo "  -o syslog_name=postfix/smtps" >> /etc/postfix/master.cf
			echo "  -o smtpd_tls_wrappermode=yes" >> /etc/postfix/master.cf
			echo "  -o smtpd_sasl_auth_enable=yes" >> /etc/postfix/master.cf
			echo "  -o smtpd_reject_unlisted_recipient=no" >> /etc/postfix/master.cf
			echo "  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject" >> /etc/postfix/master.cf
			echo "  -o milter_macro_daemon_name=ORIGINATING" >> /etc/postfix/master.cf
		fi

		# Restart Postfix to apply master.cf changes
		postfix stop 2>/dev/null
		postfix start

		# Install dovecot-pop3d if missing
		if [ ! -f /usr/libexec/dovecot/pop3 ]; then
			apk add dovecot-pop3d 2>/dev/null
		fi

		# Configure Dovecot for POP3S (995)
		if [ -f /etc/dovecot/dovecot.conf ]; then
			# Enable POP3 protocol
			if ! grep -q "protocols.*pop3" /etc/dovecot/dovecot.conf; then
				sed -i "s/^protocols = .*/& pop3/" /etc/dovecot/dovecot.conf
			fi
			# If no protocols line exists, add one
			grep -q "^protocols" /etc/dovecot/dovecot.conf || \
				echo "protocols = imap pop3 lmtp" >> /etc/dovecot/dovecot.conf

			# Configure POP3S listener - uncomment ports in 10-master.conf
			if [ -f /etc/dovecot/conf.d/10-master.conf ]; then
				# Uncomment and enable pop3s with SSL
				sed -i "/service pop3-login/,/^}/ {
					s/#port = 110/port = 110/
					s/#port = 995/port = 995/
					s/#ssl = yes/ssl = yes/
				}" /etc/dovecot/conf.d/10-master.conf

				# Also ensure IMAPS is properly enabled
				sed -i "/service imap-login/,/^}/ {
					s/#port = 143/port = 143/
					s/#port = 993/port = 993/
					s/#ssl = yes/ssl = yes/
				}" /etc/dovecot/conf.d/10-master.conf
			fi
		fi

		# Restart Dovecot to apply changes
		rc-service dovecot restart 2>/dev/null || {
			killall dovecot 2>/dev/null
			sleep 1
			dovecot
		}
	'

	log "Ports enabled. Checking status..."
	sleep 2

	# Verify ports
	local ports_status=$(lxc-attach -n "$container" -- netstat -tln 2>/dev/null)
	for port in 587 465 995; do
		if echo "$ports_status" | grep -q ":$port "; then
			log "Port $port: listening"
		else
			warn "Port $port: still not listening"
		fi
	done
}

# ============================================================================
# Logs & Diagnostics
# ============================================================================

cmd_logs() {
	local lines="${1:-50}"
	local container=$(uci_get main.container)
	container="${container:-mailserver}"

	lxc-attach -n "$container" -- tail -n "$lines" /var/log/mail.log 2>/dev/null
}

cmd_test() {
	local email="$1"
	[ -z "$email" ] && { echo "Usage: mailctl test <email@domain>"; return 1; }

	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local domain=$(uci_get main.domain)
	local hostname=$(uci_get main.hostname)

	log "Sending test email to $email..."

	lxc-attach -n "$container" -- sh -c "echo 'Test from SecuBox Mail Server' | mail -s 'Test Email' '$email'"

	log "Test email sent. Check inbox."
}

# ============================================================================
# Webmail Integration
# ============================================================================

cmd_webmail() {
	local action="${1:-status}"

	case "$action" in
		status)
			local webmail=$(uci_get webmail.container)
			webmail="${webmail:-secubox-webmail}"
			if docker ps 2>/dev/null | grep -q "$webmail"; then
				local port=$(uci_get webmail.port)
				echo "Webmail: Running on port ${port:-8026}"
			else
				echo "Webmail: Not running"
			fi
			;;
		configure)
			local domain=$(uci_get main.domain)
			local hostname=$(uci_get main.hostname)
			hostname="${hostname:-mail}"
			local fqdn="${hostname}.${domain}"

			log "Configuring webmail to connect via socat proxy..."

			local webmail=$(uci_get webmail.container)
			webmail="${webmail:-secubox-webmail}"

			# Docker containers reach host via gateway IP 172.17.0.1
			# socat proxies IMAP on 10143 and SMTP on 10025
			local docker_gateway="172.17.0.1"
			local imap_proxy_port="10143"
			local smtp_proxy_port="10025"

			# Update Roundcube config to use socat proxy (plaintext, no SSL)
			# SSL termination happens at HAProxy level for external access
			docker exec "$webmail" sh -c "cat > /var/www/html/config/config.docker.inc.php << EOF
<?php
  \\\$config['db_dsnw'] = 'sqlite:////var/roundcube/db/sqlite.db?mode=0646';
  \\\$config['db_dsnr'] = '';
  // Connect to LXC mailserver via socat proxy on host
  \\\$config['imap_host'] = '${docker_gateway}:${imap_proxy_port}';
  \\\$config['smtp_host'] = '${docker_gateway}:${smtp_proxy_port}';
  \\\$config['username_domain'] = '$domain';
  \\\$config['temp_dir'] = '/tmp/roundcube-temp';
  \\\$config['skin'] = 'elastic';
  \\\$config['request_path'] = '/';
  \\\$config['plugins'] = array_filter(array_unique(array_merge(\\\$config['plugins'], ['archive', 'zipdownload'])));
EOF"

			log "Webmail configured to use proxy at ${docker_gateway}:${imap_proxy_port}"
			log "Ensure socat proxies are running (mailserver init.d starts them)"
			;;
		*)
			echo "Webmail commands:"
			echo "  webmail status       Show webmail status"
			echo "  webmail configure    Configure webmail for this server"
			;;
	esac
}

# ============================================================================
# Daily Report
# ============================================================================

cmd_report() {
	local action="${1:-generate}"
	local admin_email=$(uci_get main.admin_email)
	admin_email="${admin_email:-root}"
	local container=$(uci_get main.container)
	container="${container:-mailserver}"
	local domain=$(uci_get main.domain)

	case "$action" in
		generate)
			local report_date=$(date '+%Y-%m-%d')
			local report_file="/tmp/mail-report-${report_date}.txt"

			cat > "$report_file" << EOF
========================================
SecuBox Mail Server Daily Report
Date: $report_date
Domain: ${domain:-not set}
========================================

=== Server Status ===
$(cmd_status 2>/dev/null | grep -v '====')

=== Mail Queue ===
$(lxc-attach -n "$container" -- mailq 2>/dev/null | head -20)

=== Recent Mail Log (last 50 lines) ===
$(lxc-attach -n "$container" -- tail -50 /var/log/mail.log 2>/dev/null)

=== Storage Usage ===
$(du -sh /srv/mailserver/* 2>/dev/null)

=== Active Connections ===
$(lxc-attach -n "$container" -- netstat -tn 2>/dev/null | grep -E ':25|:143|:993|:587' | head -20)

EOF
			echo "Report generated: $report_file"
			echo "$report_file"
			;;

		send)
			local report_file=$(cmd_report generate | tail -1)
			if [ -f "$report_file" ]; then
				log "Sending daily report to $admin_email..."
				lxc-attach -n "$container" -- sh -c "cat '$report_file' | mail -s 'SecuBox Mail Daily Report' '$admin_email'"
				log "Report sent to $admin_email"
			else
				error "Failed to generate report"
				return 1
			fi
			;;

		enable)
			# Setup cron job for daily report
			local cron_file="/etc/cron.d/secubox-mail-report"
			cat > "$cron_file" << 'EOF'
# SecuBox Mail Server Daily Report
# Runs at 7:00 AM daily
0 7 * * * root /usr/sbin/mailctl report send >/dev/null 2>&1
EOF
			chmod 644 "$cron_file"
			log "Daily report enabled (7:00 AM)"
			;;

		disable)
			rm -f /etc/cron.d/secubox-mail-report
			log "Daily report disabled"
			;;

		*)
			echo "Report commands:"
			echo "  report generate      Generate report to file"
			echo "  report send          Generate and send to admin"
			echo "  report enable        Enable daily report (7 AM)"
			echo "  report disable       Disable daily report"
			;;
	esac
}

# ============================================================================
# Autoconfig / Autodiscover Setup
# ============================================================================

cmd_autoconfig_setup() {
	local domain=$(uci_get main.domain)
	local hostname=$(uci_get main.hostname)
	hostname="${hostname:-mail}"
	local mail_fqdn="${hostname}.${domain}"
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"

	if [ -z "$domain" ]; then
		error "Domain not configured. Set with: uci set mailserver.main.domain=example.com"
		return 1
	fi

	log "Setting up mail autoconfig for $domain..."

	local autoconfig_dir="$data_path/autoconfig"
	mkdir -p "$autoconfig_dir/mail"
	mkdir -p "$autoconfig_dir/autodiscover"

	# Thunderbird autoconfig (config-v1.1.xml)
	cat > "$autoconfig_dir/mail/config-v1.1.xml" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
  <emailProvider id="$domain">
    <domain>$domain</domain>
    <displayName>$domain Mail</displayName>
    <displayShortName>$domain</displayShortName>
    <incomingServer type="imap">
      <hostname>$mail_fqdn</hostname>
      <port>993</port>
      <socketType>SSL</socketType>
      <authentication>password-cleartext</authentication>
      <username>%EMAILADDRESS%</username>
    </incomingServer>
    <incomingServer type="imap">
      <hostname>$mail_fqdn</hostname>
      <port>143</port>
      <socketType>STARTTLS</socketType>
      <authentication>password-cleartext</authentication>
      <username>%EMAILADDRESS%</username>
    </incomingServer>
    <outgoingServer type="smtp">
      <hostname>$mail_fqdn</hostname>
      <port>587</port>
      <socketType>STARTTLS</socketType>
      <authentication>password-cleartext</authentication>
      <username>%EMAILADDRESS%</username>
    </outgoingServer>
    <outgoingServer type="smtp">
      <hostname>$mail_fqdn</hostname>
      <port>465</port>
      <socketType>SSL</socketType>
      <authentication>password-cleartext</authentication>
      <username>%EMAILADDRESS%</username>
    </outgoingServer>
  </emailProvider>
</clientConfig>
EOF

	# Outlook/ActiveSync autodiscover (autodiscover.xml)
	cat > "$autoconfig_dir/autodiscover/autodiscover.xml" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
  <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
    <Account>
      <AccountType>email</AccountType>
      <Action>settings</Action>
      <Protocol>
        <Type>IMAP</Type>
        <Server>$mail_fqdn</Server>
        <Port>993</Port>
        <DomainRequired>off</DomainRequired>
        <LoginName></LoginName>
        <SPA>off</SPA>
        <SSL>on</SSL>
        <AuthRequired>on</AuthRequired>
      </Protocol>
      <Protocol>
        <Type>SMTP</Type>
        <Server>$mail_fqdn</Server>
        <Port>587</Port>
        <DomainRequired>off</DomainRequired>
        <LoginName></LoginName>
        <SPA>off</SPA>
        <Encryption>TLS</Encryption>
        <AuthRequired>on</AuthRequired>
        <UsePOPAuth>on</UsePOPAuth>
        <SMTPLast>off</SMTPLast>
      </Protocol>
    </Account>
  </Response>
</Autodiscover>
EOF

	# Apple mobileconfig profile
	cat > "$autoconfig_dir/$domain.mobileconfig" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>PayloadContent</key>
  <array>
    <dict>
      <key>EmailAccountDescription</key>
      <string>$domain Mail</string>
      <key>EmailAccountName</key>
      <string>$domain</string>
      <key>EmailAccountType</key>
      <string>EmailTypeIMAP</string>
      <key>EmailAddress</key>
      <string></string>
      <key>IncomingMailServerAuthentication</key>
      <string>EmailAuthPassword</string>
      <key>IncomingMailServerHostName</key>
      <string>$mail_fqdn</string>
      <key>IncomingMailServerPortNumber</key>
      <integer>993</integer>
      <key>IncomingMailServerUseSSL</key>
      <true/>
      <key>IncomingMailServerUsername</key>
      <string></string>
      <key>OutgoingMailServerAuthentication</key>
      <string>EmailAuthPassword</string>
      <key>OutgoingMailServerHostName</key>
      <string>$mail_fqdn</string>
      <key>OutgoingMailServerPortNumber</key>
      <integer>587</integer>
      <key>OutgoingMailServerUseSSL</key>
      <true/>
      <key>OutgoingMailServerUsername</key>
      <string></string>
      <key>OutgoingPasswordSameAsIncomingPassword</key>
      <true/>
      <key>PayloadDescription</key>
      <string>Email account configuration for $domain</string>
      <key>PayloadDisplayName</key>
      <string>$domain Email</string>
      <key>PayloadIdentifier</key>
      <string>com.$domain.email</string>
      <key>PayloadType</key>
      <string>com.apple.mail.managed</string>
      <key>PayloadUUID</key>
      <string>$(cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "12345678-1234-1234-1234-123456789012")</string>
      <key>PayloadVersion</key>
      <integer>1</integer>
    </dict>
  </array>
  <key>PayloadDisplayName</key>
  <string>$domain Mail Configuration</string>
  <key>PayloadIdentifier</key>
  <string>com.$domain.profile</string>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadUUID</key>
  <string>$(cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "87654321-4321-4321-4321-210987654321")</string>
  <key>PayloadVersion</key>
  <integer>1</integer>
</dict>
</plist>
EOF

	log "Autoconfig files created in $autoconfig_dir"

	# Setup DNS SRV records via dnsctl if available
	if command -v dnsctl >/dev/null 2>&1; then
		log "Setting up DNS autodiscover records..."

		# Autoconfig/Autodiscover CNAME records
		# Syntax: dnsctl add <TYPE> <subdomain> <target>
		dnsctl add CNAME "autoconfig" "$mail_fqdn." 2>/dev/null || true
		dnsctl add CNAME "autodiscover" "$mail_fqdn." 2>/dev/null || true

		# SRV records for autodiscover (if supported by provider)
		dnsctl add SRV "_autodiscover._tcp" "0 1 443 $mail_fqdn." 2>/dev/null || true
		dnsctl add SRV "_imaps._tcp" "0 1 993 $mail_fqdn." 2>/dev/null || true
		dnsctl add SRV "_submission._tcp" "0 1 587 $mail_fqdn." 2>/dev/null || true

		log "DNS records configured"
	else
		warn "dnsctl not found - add DNS records manually:"
		echo "  autoconfig.$domain    CNAME  $mail_fqdn"
		echo "  autodiscover.$domain  CNAME  $mail_fqdn"
		echo "  _autodiscover._tcp.$domain  SRV  0 1 443 $mail_fqdn"
		echo "  _imaps._tcp.$domain         SRV  0 1 993 $mail_fqdn"
		echo "  _submission._tcp.$domain    SRV  0 1 587 $mail_fqdn"
	fi

	# Register with HAProxy for autoconfig serving
	if [ -x /usr/sbin/haproxyctl ]; then
		log "Registering autoconfig with HAProxy..."

		# Check if autoconfig vhost exists
		local vhost_exists=$(uci show haproxy 2>/dev/null | grep "autoconfig_${domain//\./_}" || true)

		if [ -z "$vhost_exists" ]; then
			# Create a simple static file server for autoconfig
			# HAProxy will serve these files
			uci add haproxy vhost >/dev/null
			uci set haproxy.@vhost[-1].name="autoconfig_${domain//\./_}"
			uci set haproxy.@vhost[-1].domain="autoconfig.$domain"
			uci set haproxy.@vhost[-1].backend="autoconfig_backend"
			uci set haproxy.@vhost[-1].ssl='1'
			uci set haproxy.@vhost[-1].acme='1'
			uci set haproxy.@vhost[-1].enabled='1'

			uci add haproxy vhost >/dev/null
			uci set haproxy.@vhost[-1].name="autodiscover_${domain//\./_}"
			uci set haproxy.@vhost[-1].domain="autodiscover.$domain"
			uci set haproxy.@vhost[-1].backend="autoconfig_backend"
			uci set haproxy.@vhost[-1].ssl='1'
			uci set haproxy.@vhost[-1].acme='1'
			uci set haproxy.@vhost[-1].enabled='1'

			uci commit haproxy
			log "HAProxy vhosts created for autoconfig.$domain and autodiscover.$domain"
		fi
	fi

	log ""
	log "Autoconfig setup complete!"
	log ""
	log "Thunderbird: https://autoconfig.$domain/mail/config-v1.1.xml"
	log "Outlook:     https://autodiscover.$domain/autodiscover/autodiscover.xml"
	log "Apple:       https://$mail_fqdn/$domain.mobileconfig"
	log ""
	log "DNS records needed:"
	log "  autoconfig.$domain    CNAME  $mail_fqdn"
	log "  autodiscover.$domain  CNAME  $mail_fqdn"
}

cmd_autoconfig_status() {
	local domain=$(uci_get main.domain)
	local hostname=$(uci_get main.hostname)
	hostname="${hostname:-mail}"
	local data_path=$(uci_get main.data_path)
	data_path="${data_path:-/srv/mailserver}"
	local autoconfig_dir="$data_path/autoconfig"

	echo "Autoconfig Status for $domain"
	echo "=============================="
	echo ""

	if [ -f "$autoconfig_dir/mail/config-v1.1.xml" ]; then
		echo "Thunderbird config: OK"
	else
		echo "Thunderbird config: NOT FOUND"
	fi

	if [ -f "$autoconfig_dir/autodiscover/autodiscover.xml" ]; then
		echo "Outlook config:     OK"
	else
		echo "Outlook config:     NOT FOUND"
	fi

	if [ -f "$autoconfig_dir/$domain.mobileconfig" ]; then
		echo "Apple config:       OK"
	else
		echo "Apple config:       NOT FOUND"
	fi

	echo ""
	echo "DNS Check:"
	echo "----------"
	host autoconfig.$domain 2>/dev/null | head -1 || echo "autoconfig.$domain: NOT RESOLVED"
	host autodiscover.$domain 2>/dev/null | head -1 || echo "autodiscover.$domain: NOT RESOLVED"
}

# ============================================================================
# Firewall Setup
# ============================================================================

cmd_firewall_setup() {
	local container=$(uci_get main.container)
	container="${container:-mailserver}"

	# Get mail server IP
	local mail_ip=$(lxc-info -n "$container" -iH 2>/dev/null | head -1)
	if [ -z "$mail_ip" ]; then
		mail_ip="192.168.255.30"
		warn "Container not running, using default IP: $mail_ip"
	fi

	# Get LAN subnet
	local lan_ip=$(uci -q get network.lan.ipaddr)
	local lan_subnet="${lan_ip%.*}.0/24"

	log "Setting up mail firewall rules..."
	log "Mail server IP: $mail_ip"
	log "LAN subnet: $lan_subnet (excluded from redirect)"

	# Create firewall.user rules
	local fw_file="/etc/firewall.user"
	local fw_backup="${fw_file}.bak"

	# Backup existing file
	[ -f "$fw_file" ] && cp "$fw_file" "$fw_backup"

	# Remove old mail rules and add new ones
	local tmpfile="/tmp/firewall.user.$$"
	if [ -f "$fw_file" ]; then
		grep -v "mailserver\|192.168.255.30\|dport 143\|dport 993\|dport 25\|dport 465\|dport 587" "$fw_file" > "$tmpfile" 2>/dev/null || true
	else
		touch "$tmpfile"
	fi

	cat >> "$tmpfile" << EOF

# SecuBox Mail Server Firewall Rules
# Redirect mail ports to local mailserver - EXCLUDING LAN clients
# LAN clients can still reach external mail servers (OVH, Gmail, etc.)
iptables -t nat -A PREROUTING ! -s $lan_subnet -p tcp --dport 143 -j DNAT --to-destination ${mail_ip}:143
iptables -t nat -A PREROUTING ! -s $lan_subnet -p tcp --dport 993 -j DNAT --to-destination ${mail_ip}:993
iptables -t nat -A PREROUTING ! -s $lan_subnet -p tcp --dport 25 -j DNAT --to-destination ${mail_ip}:25
iptables -t nat -A PREROUTING ! -s $lan_subnet -p tcp --dport 465 -j DNAT --to-destination ${mail_ip}:465
iptables -t nat -A PREROUTING ! -s $lan_subnet -p tcp --dport 587 -j DNAT --to-destination ${mail_ip}:587

# Allow forwarding to mailserver
iptables -A FORWARD -d $mail_ip -p tcp -m multiport --dports 25,143,465,587,993 -j ACCEPT
EOF

	mv "$tmpfile" "$fw_file"
	chmod 644 "$fw_file"

	# Apply rules immediately (firewall reload runs firewall.user automatically)
	log "Applying firewall rules..."
	/etc/init.d/firewall reload 2>/dev/null

	log "Firewall setup complete"
	log "WAN traffic on mail ports -> redirected to local mailserver"
	log "LAN clients -> can reach external mail servers directly"
}

cmd_firewall_clear() {
	log "Removing mail firewall rules..."

	# Remove DNAT rules
	for port in 143 993 25 465 587; do
		iptables -t nat -D PREROUTING -p tcp --dport $port -j DNAT --to-destination 192.168.255.30:$port 2>/dev/null || true
		# Also try with ! -s prefix
		for subnet in "192.168.255.0/24" "192.168.1.0/24" "10.0.0.0/8"; do
			iptables -t nat -D PREROUTING ! -s $subnet -p tcp --dport $port -j DNAT --to-destination 192.168.255.30:$port 2>/dev/null || true
		done
	done

	# Remove from firewall.user
	local fw_file="/etc/firewall.user"
	if [ -f "$fw_file" ]; then
		local tmpfile="/tmp/firewall.user.$$"
		grep -v "mailserver\|192.168.255.30\|dport 143\|dport 993\|dport 25\|dport 465\|dport 587" "$fw_file" > "$tmpfile" 2>/dev/null || true
		mv "$tmpfile" "$fw_file"
	fi

	log "Mail firewall rules removed"
}

# ============================================================================
# Help
# ============================================================================

show_help() {
	cat << EOF
SecuBox Mail Server v$VERSION

Usage: mailctl <command> [options]

Setup:
  install              Create and configure mail server
  uninstall            Remove mail server
  dns-setup            Set up MX/SPF/DKIM/DMARC via dnsctl
  ssl-setup            Obtain SSL certificate
  firewall-setup       Setup mail port forwarding (WAN only)
  firewall-clear       Remove mail firewall rules
  autoconfig-setup     Setup autodiscover for mail clients
  autoconfig-status    Check autoconfig status

Service:
  start                Start mail server
  stop                 Stop mail server
  restart              Restart mail server
  status               Show server status

Users:
  user add <email>     Add mail user
  user del <email>     Delete mail user
  user list            List all users
  user passwd <email>  Change password

Aliases:
  alias add <a> <t>    Add email alias
  alias list           List aliases

Mesh Backup:
  mesh backup          Create backup
  mesh restore <file>  Restore from backup
  mesh sync            Sync with peers
  mesh peers           List mesh peers

Webmail:
  webmail status       Show webmail status
  webmail configure    Configure for this server

Reports:
  report generate      Generate status report
  report send          Send report to admin
  report enable        Enable daily report (7 AM)
  report disable       Disable daily report

Diagnostics:
  logs [lines]         View mail logs
  test <email>         Send test email
  ssl-status           Show SSL cert info
  fix-postfix          Fix LMDB maps and DNS resolution
  fix-ports            Enable submission/smtps/pop3s ports
  firewall-setup       Setup mail port forwarding (WAN only)
  firewall-clear       Remove mail firewall rules

Examples:
  mailctl install
  mailctl user add user@example.com
  mailctl dns-setup
  mailctl mesh sync push

EOF
}

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

case "${1:-}" in
	install)     shift; cmd_install "$@" ;;
	uninstall)   shift; cmd_uninstall "$@" ;;
	start)       shift; cmd_start "$@" ;;
	stop)        shift; cmd_stop "$@" ;;
	restart)     shift; cmd_restart "$@" ;;
	status)      shift; cmd_status "$@" ;;
	user)        shift; cmd_user "$@" ;;
	alias)       shift; cmd_alias "$@" ;;
	ssl-setup)   shift; cmd_ssl_setup "$@" ;;
	ssl-status)  shift; cmd_ssl_status "$@" ;;
	dns-setup)   shift; cmd_dns_setup "$@" ;;
	mesh)        shift; cmd_mesh "$@" ;;
	webmail)     shift; cmd_webmail "$@" ;;
	logs)        shift; cmd_logs "$@" ;;
	test)        shift; cmd_test "$@" ;;
	report)      shift; cmd_report "$@" ;;
	fix-postfix) shift; cmd_fix_postfix "$@" ;;
	fix-ports)   shift; cmd_fix_ports "$@" ;;
	firewall-setup) shift; cmd_firewall_setup "$@" ;;
	firewall-clear) shift; cmd_firewall_clear "$@" ;;
	autoconfig-setup) shift; cmd_autoconfig_setup "$@" ;;
	autoconfig-status) shift; cmd_autoconfig_status "$@" ;;
	help|--help|-h|'') show_help ;;
	*)           error "Unknown command: $1"; show_help >&2; exit 1 ;;
esac

exit 0
