#!/bin/bash
# AirwavePBX Installation Repair Script
# Fixes common configuration and startup issues

set +e  # Don't exit on errors

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

# Configuration
INSTALL_DIR="/opt/airwavepbx"
DATA_DIR="/var/lib/airwavepbx"
LOG_DIR="/var/log/airwavepbx"
CONFIG_FILE="$INSTALL_DIR/config.yaml"
BACKUP_CONFIG="$INSTALL_DIR/config.yaml.backup"

print_banner() {
    echo -e "${BLUE}${BOLD}"
    echo "╔══════════════════════════════════════════════════════════════════════╗"
    echo "║                    AirwavePBX Repair Tool v1.0                      ║"
    echo "║                      Diagnosis & Fix Script                         ║"
    echo "╚══════════════════════════════════════════════════════════════════════╝"
    echo -e "${NC}"
}

print_step() {
    echo -e "\n${BLUE}${BOLD}▶ $1${NC}"
}

print_info() {
    echo -e "  ${CYAN}ℹ $1${NC}"
}

print_success() {
    echo -e "  ${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "  ${RED}✗ $1${NC}"
}

print_warning() {
    echo -e "  ${YELLOW}⚠ $1${NC}"
}

# Check if running as root
check_root() {
    if [[ $EUID -ne 0 ]]; then
        print_error "This script must be run as root"
        echo "Usage: sudo $0"
        exit 1
    fi
}

# Backup current config
backup_config() {
    print_step "Backing Up Current Configuration"
    
    if [[ -f "$CONFIG_FILE" ]]; then
        cp "$CONFIG_FILE" "$BACKUP_CONFIG"
        print_success "Configuration backed up to $BACKUP_CONFIG"
    else
        print_warning "No existing configuration found"
    fi
}

# Check and create airwave user
fix_user() {
    print_step "Checking AirwavePBX User"
    
    if ! id "airwave" &>/dev/null; then
        print_info "Creating airwave user..."
        useradd -r -s /bin/false -d /opt/airwavepbx airwave
        print_success "User 'airwave' created"
    else
        print_success "User 'airwave' exists"
    fi
}

# Fix directory permissions
fix_permissions() {
    print_step "Fixing Directory Permissions"
    
    # Create directories if they don't exist
    mkdir -p "$INSTALL_DIR" "$DATA_DIR" "$LOG_DIR"
    
    # Fix ownership
    chown -R airwave:airwave "$INSTALL_DIR"
    chown -R airwave:airwave "$DATA_DIR" 
    chown -R airwave:airwave "$LOG_DIR"
    
    # Fix permissions
    chmod 755 "$INSTALL_DIR"
    chmod 755 "$DATA_DIR"
    chmod 755 "$LOG_DIR"
    
    if [[ -f "$INSTALL_DIR/airwavepbx" ]]; then
        chmod +x "$INSTALL_DIR/airwavepbx"
        print_success "Binary permissions fixed"
    else
        print_error "AirwavePBX binary not found at $INSTALL_DIR/airwavepbx"
    fi
    
    print_success "Permissions fixed"
}

# Get AMI password from Asterisk config
get_ami_password() {
    local ami_password=""
    if [[ -f "/etc/asterisk/manager.conf" ]]; then
        ami_password=$(grep -A 10 "^\[airwave\]" /etc/asterisk/manager.conf | grep "^secret" | cut -d'=' -f2 | tr -d ' ')
    fi
    echo "$ami_password"
}

# Create proper configuration file
create_config() {
    print_step "Creating Proper Configuration File"
    
    local ami_password=$(get_ami_password)
    
    if [[ -z "$ami_password" ]]; then
        print_error "Cannot find AMI password in Asterisk configuration"
        return 1
    fi
    
    print_info "Found AMI password: ${ami_password:0:8}..."
    
    # Generate other passwords if needed
    local admin_password="${ADMIN_PASSWORD:-$(openssl rand -base64 12 | tr -d '=+/' | cut -c1-16)}"
    local api_key="${API_KEY:-$(openssl rand -hex 32)}"
    
    # Create config file using printf to avoid indentation issues
    printf 'server:
  host: "0.0.0.0"
  port: 8080
  tls_enabled: false
  tls_cert: "/opt/airwavepbx/ssl/fullchain.pem"
  tls_key: "/opt/airwavepbx/ssl/privkey.pem"

database:
  path: "/var/lib/airwavepbx/airwavepbx.db"

asterisk:
  ami_host: "127.0.0.1"
  ami_port: 5038
  ami_username: "airwave"
  ami_password: "%s"

admin:
  username: "admin"
  password: "%s"

api:
  key: "%s"
  cors_origins: ["*"]

logging:
  level: "info"
  path: "/var/log/airwavepbx/airwavepbx.log"
' "$ami_password" "$admin_password" "$api_key" > "$CONFIG_FILE"
    
    chown airwave:airwave "$CONFIG_FILE"
    chmod 600 "$CONFIG_FILE"
    
    print_success "Configuration file created"
    
    # Save credentials
    cat > "/root/airwavepbx-repair-credentials.txt" << EOF
# AirwavePBX Credentials (Generated by Repair Tool)
# Generated: $(date)

Admin Login:
Username: admin
Password: $admin_password

API Key: $api_key

AMI Password: $ami_password
EOF
    
    print_success "Credentials saved to /root/airwavepbx-repair-credentials.txt"
}

# Test configuration syntax
test_config() {
    print_step "Testing Configuration Syntax"
    
    if ! command -v python3 &> /dev/null; then
        print_warning "Python3 not available for YAML validation"
        return 0
    fi
    
    python3 -c "import yaml; yaml.safe_load(open('$CONFIG_FILE'))" 2>/dev/null
    if [[ $? -eq 0 ]]; then
        print_success "YAML syntax is valid"
    else
        print_error "YAML syntax has errors"
        return 1
    fi
}

# Test Asterisk AMI connection
test_ami() {
    print_step "Testing Asterisk AMI Connection"
    
    if ! systemctl is-active --quiet asterisk; then
        print_warning "Asterisk is not running, starting it..."
        systemctl start asterisk
        sleep 3
    fi
    
    # Test if AMI port is listening
    if netstat -ln | grep -q ":5038 "; then
        print_success "AMI port 5038 is listening"
    else
        print_error "AMI port 5038 is not listening"
        return 1
    fi
    
    # Test AMI user exists
    local ami_users=$(asterisk -rx "manager show users" 2>/dev/null)
    if echo "$ami_users" | grep -q "airwave"; then
        print_success "AMI user 'airwave' exists in Asterisk"
    else
        print_error "AMI user 'airwave' not found in Asterisk"
        return 1
    fi
}

# Test binary execution
test_binary() {
    print_step "Testing AirwavePBX Binary"
    
    if [[ ! -f "$INSTALL_DIR/airwavepbx" ]]; then
        print_error "AirwavePBX binary not found"
        return 1
    fi
    
    if [[ ! -x "$INSTALL_DIR/airwavepbx" ]]; then
        print_error "AirwavePBX binary is not executable"
        return 1
    fi
    
    print_info "Testing configuration loading..."
    cd "$INSTALL_DIR"
    
    # Test config loading with timeout
    timeout 10s sudo -u airwave "$INSTALL_DIR/airwavepbx" -config "$CONFIG_FILE" --help &>/dev/null
    local exit_code=$?
    
    if [[ $exit_code -eq 0 ]] || [[ $exit_code -eq 124 ]]; then
        print_success "Binary can load configuration"
    else
        print_error "Binary failed to load configuration"
        
        # Try to get more details
        print_info "Attempting to get error details..."
        timeout 5s sudo -u airwave "$INSTALL_DIR/airwavepbx" -config "$CONFIG_FILE" 2>&1 | head -5
        return 1
    fi
}

# Fix systemd service
fix_systemd_service() {
    print_step "Fixing Systemd Service"
    
    cat > /etc/systemd/system/airwavepbx.service << EOF
[Unit]
Description=AirwavePBX Professional Broadcasting PBX
After=network.target asterisk.service
Requires=asterisk.service

[Service]
Type=simple
User=airwave
Group=airwave
WorkingDirectory=/opt/airwavepbx
ExecStart=/opt/airwavepbx/airwavepbx -config /opt/airwavepbx/config.yaml
Restart=always
RestartSec=10
StandardOutput=append:/var/log/airwavepbx/airwavepbx.log
StandardError=append:/var/log/airwavepbx/airwavepbx.log

# Security
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF
    
    systemctl daemon-reload
    systemctl enable airwavepbx
    
    print_success "Systemd service updated"
}

# Test service startup
test_service() {
    print_step "Testing Service Startup"
    
    systemctl stop airwavepbx &>/dev/null
    
    print_info "Starting AirwavePBX service..."
    systemctl start airwavepbx
    
    sleep 5
    
    if systemctl is-active --quiet airwavepbx; then
        print_success "AirwavePBX service is running"
        
        # Test if it's listening on the configured port
        local port=$(grep -A 5 "^server:" "$CONFIG_FILE" | grep "port:" | cut -d':' -f2 | tr -d ' ')
        if netstat -ln | grep -q ":$port "; then
            print_success "AirwavePBX is listening on port $port"
        else
            print_warning "AirwavePBX service is running but not listening on port $port"
        fi
    else
        print_error "AirwavePBX service failed to start"
        
        print_info "Recent service logs:"
        journalctl -u airwavepbx -n 10 --no-pager
        return 1
    fi
}

# Run full diagnostic
run_diagnostics() {
    print_banner
    
    check_root
    backup_config
    fix_user
    fix_permissions
    create_config
    test_config
    test_ami
    test_binary
    fix_systemd_service
    test_service
    
    print_step "Repair Summary"
    
    if systemctl is-active --quiet airwavepbx; then
        print_success "AirwavePBX is now running successfully!"
        echo ""
        print_info "Service Status:"
        systemctl status airwavepbx --no-pager -l
        echo ""
        print_info "Access your AirwavePBX at: http://$(hostname -I | awk '{print $1}'):8080"
        print_info "Credentials are saved in: /root/airwavepbx-repair-credentials.txt"
    else
        print_error "AirwavePBX is still not running properly"
        print_info "Check logs with: journalctl -u airwavepbx -f"
    fi
}

# Menu system
show_menu() {
    clear
    print_banner
    echo ""
    echo "Select repair action:"
    echo "1) Full diagnostic and repair"
    echo "2) Fix user and permissions only"
    echo "3) Recreate configuration file"
    echo "4) Test configuration"
    echo "5) Test service startup"
    echo "6) View service logs"
    echo "7) Restore backup configuration"
    echo "0) Exit"
    echo ""
    read -p "Choose option [1]: " choice
    choice=${choice:-1}
}

# Main execution
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    if [[ $# -eq 0 ]]; then
        while true; do
            show_menu
            case $choice in
                1) run_diagnostics; read -p "Press Enter to continue..."; ;;
                2) check_root; fix_user; fix_permissions; read -p "Press Enter to continue..."; ;;
                3) check_root; create_config; read -p "Press Enter to continue..."; ;;
                4) test_config; read -p "Press Enter to continue..."; ;;
                5) check_root; test_service; read -p "Press Enter to continue..."; ;;
                6) echo "Recent logs:"; journalctl -u airwavepbx -n 20 --no-pager; read -p "Press Enter to continue..."; ;;
                7) check_root; [[ -f "$BACKUP_CONFIG" ]] && cp "$BACKUP_CONFIG" "$CONFIG_FILE" && print_success "Configuration restored" || print_error "No backup found"; read -p "Press Enter to continue..."; ;;
                0) exit 0; ;;
                *) echo "Invalid option"; sleep 1; ;;
            esac
        done
    else
        # Command line mode
        case $1 in
            "full") run_diagnostics ;;
            "permissions") check_root; fix_user; fix_permissions ;;
            "config") check_root; create_config ;;
            "test") test_config; test_ami; test_binary ;;
            "service") check_root; test_service ;;
            *) echo "Usage: $0 [full|permissions|config|test|service]" ;;
        esac
    fi
fi