#!/bin/bash
set -euo pipefail

# Conduit Matrix Homeserver Deployment Script
# Usage: ./deploy-conduit.sh [install|start|stop|logs|status|backup]
# 
# See upstream: timmy-config#166, timmy-config#183
# Dependency: prerequisites.md completed

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MATRIX_DIR="$(dirname "$SCRIPT_DIR")"
CONDUIT_DIR="$MATRIX_DIR/conduit"
BACKUP_DIR="$MATRIX_DIR/backups"

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

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

preflight_check() {
    log_info "Running preflight checks..."
    
    # Check Docker
    if ! command -v docker &> /dev/null; then
        log_error "Docker not found. Install per prerequisites.md"
        exit 1
    fi
    
    # Check Docker Compose
    if ! docker compose version &> /dev/null && ! docker-compose version &> /dev/null; then
        log_error "Docker Compose not found. Install per prerequisites.md"
        exit 1
    fi
    
    # Check .env exists
    if [[ ! -f "$CONDUIT_DIR/.env" ]]; then
        log_error ".env file missing at $CONDUIT_DIR/.env"
        log_warn "Copy from .env.example and configure:"
        log_warn "  cp $CONDUIT_DIR/.env.example $CONDUIT_DIR/.env"
        log_warn "  nano $CONDUIT_DIR/.env"
        exit 1
    fi
    
    # Check config values
    if grep -q "CHANGE_THIS" "$CONDUIT_DIR/.env"; then
        log_error ".env contains placeholder values"
        log_warn "Edit $CONDUIT_DIR/.env and set real values"
        exit 1
    fi
    
    # Check ports
    for port in 80 443 8448; do
        if ss -tlnp | grep -q ":$port "; then
            log_warn "Port $port is already in use"
        fi
    done
    
    log_info "Preflight checks passed"
}

cmd_install() {
    log_info "Installing Conduit Matrix homeserver..."
    preflight_check
    
    # Create data directory
    mkdir -p "$CONDUIT_DIR/data"
    
    # Set permissions
    # Conduit runs as uid 1000 inside container
    sudo chown -R 1000:1000 "$CONDUIT_DIR/data" || true
    
    # Pull images
    cd "$CONDUIT_DIR"
    docker compose pull
    
    log_info "Installation complete. Run './deploy-conduit.sh start' to begin"
    log_warn "IMPORTANT: Create admin account immediately after first start"
    log_warn "  docker exec -it matrix-conduit register_new_matrix_user -c /var/lib/matrix-conduit" 
}

cmd_start() {
    log_info "Starting Conduit Matrix homeserver..."
    cd "$CONDUIT_DIR"
    docker compose up -d
    
    log_info "Waiting for healthcheck..."
    sleep 5
    
    # Wait for healthy
    for i in {1..30}; do
        if docker compose ps conduit | grep -q "healthy"; then
            log_info "Conduit is healthy and running!"
            log_info "Server URL: https://$(grep DOMAIN .env | cut -d'=' -f2 | tr -d '"')"
            return 0
        fi
        echo -n "."
        sleep 2
    done
    
    log_error "Conduit failed to become healthy"
    docker compose logs --tail=50 conduit
    exit 1
}

cmd_stop() {
    log_info "Stopping Conduit Matrix homeserver..."
    cd "$CONDUIT_DIR"
    docker compose down
    log_info "Conduit stopped"
}

cmd_logs() {
    cd "$CONDUIT_DIR"
    docker compose logs -f "$@"
}

cmd_status() {
    log_info "Matrix/Conduit Status:"
    cd "$CONDUIT_DIR"
    docker compose ps
    
    # Federation check
    DOMAIN=$(grep DOMAIN .env | cut -d'=' -f2 | tr -d '"')
    log_info "Federation check:"
    curl -s "https://$DOMAIN/.well-known/matrix/server" 2>/dev/null | head -5 || echo "Server info not available (expected if not yet running)"
}

cmd_backup() {
    local backup_name="conduit-$(date +%Y%m%d-%H%M%S).tar.gz"
    mkdir -p "$BACKUP_DIR"
    
    log_info "Creating backup: $backup_name"
    
    # Stop conduit briefly for consistent backup
    cd "$CONDUIT_DIR"
    docker compose stop conduit
    
    tar czf "$BACKUP_DIR/$backup_name" -C "$CONDUIT_DIR" data
    
    docker compose start conduit
    
    log_info "Backup complete: $BACKUP_DIR/$backup_name"
}

cmd_admin() {
    log_info "Opening admin shell in Conduit container..."
    log_warn "Use: register_new_matrix_user -c /var/lib/matrix-conduit for account creation"
    docker exec -it matrix-conduit bash
}

# Main command dispatcher
case "${1:-help}" in
    install)
        cmd_install
        ;;
    start)
        cmd_start
        ;;
    stop)
        cmd_stop
        ;;
    restart)
        cmd_stop
        sleep 2
        cmd_start
        ;;
    logs)
        shift
        cmd_logs "$@"
        ;;
    status)
        cmd_status
        ;;
    backup)
        cmd_backup
        ;;
    admin)
        cmd_admin
        ;;
    *)
        echo "Conduit Matrix Homeserver Deployment"
        echo "Usage: $0 {install|start|stop|restart|logs|status|backup|admin}"
        echo ""
        echo "Commands:"
        echo "  install  - Initial setup and image download"
        echo "  start    - Start the homeserver"
        echo "  stop     - Stop the homeserver"
        echo "  restart  - Restart services"
        echo "  logs     - View container logs"
        echo "  status   - Check service status"
        echo "  backup   - Create data backup"
        echo "  admin    - Open admin shell"
        echo ""
        echo "Prerequisites: Docker, Docker Compose, configured .env file"
        echo "See: infra/matrix/prerequisites.md"
        exit 1
        ;;
esac
