#!/usr/bin/bash
set -eo pipefail

# FlightCtl Observability Configuration Renderer
# This script updates observability configuration from service-config.yaml
# Use systemd targets to start/stop services: systemctl start flightctl-observability.target

echo "FlightCtl Observability Configuration Renderer"
echo "=============================================="
echo

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo "This command must be run as root (use sudo)"
    exit 1
fi

LOG_TAG="flightctl-observability-render"

log() {
    local level="$1"
    shift
    logger -t "$LOG_TAG" "$level: $*"
    echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $*" >&2
}

check_prerequisites() {
    log "INFO" "Checking prerequisites..."
    
    # Check if service-config.yaml exists
    if [ ! -f "/etc/flightctl/service-config.yaml" ]; then
        log "ERROR" "Configuration file /etc/flightctl/service-config.yaml not found"
        exit 1
    fi
    
    # Check what observability components are installed
    local has_full_observability=false
    local has_otel_only=false
    
    # Check if full observability stack is installed
    if [ -f "/etc/flightctl/definitions/observability.defs" ]; then
        has_full_observability=true
    fi
    
    # Check if standalone OpenTelemetry collector is installed
    if [ -f "/etc/flightctl/definitions/telemetry-gateway.defs" ]; then
        has_otel_only=true
    fi
    
    if [ "$has_full_observability" = false ] && [ "$has_otel_only" = false ]; then
        log "ERROR" "No observability components found. Please install flightctl-observability or flightctl-telemetry-gateway package"
        exit 1
    fi
    
    log "INFO" "Prerequisites check passed"
}

render_observability_config() {
    log "INFO" "Rendering observability configuration..."
    
    # Check if full observability stack definitions file exists
    if [ -f "/etc/flightctl/definitions/observability.defs" ]; then
        local config_file="/etc/flightctl/service-config.yaml"
        local templates_dir="/opt/flightctl-observability/templates"
        local definitions_file="/etc/flightctl/definitions/observability.defs"
        
        # Source shared logic and call rendering with observability specific definitions
        if [ -f "/etc/flightctl/scripts/render-templates.sh" ]; then
            if ! source /etc/flightctl/scripts/render-templates.sh; then
                log "ERROR" "Failed to source render-templates.sh"
                exit 1
            fi
            
            if ! render_templates "$config_file" "$templates_dir" "$definitions_file"; then
                log "ERROR" "Failed to render observability configuration"
                exit 1
            fi
            log "INFO" "Observability configuration rendered successfully"
        else
            log "ERROR" "render-templates.sh not found"
            exit 1
        fi
    else
        log "INFO" "Full observability stack not installed, skipping"
    fi
}

render_telemetry_gateway_config() {
    log "INFO" "Rendering OpenTelemetry collector configuration..."
    
    # Check if otel-collector definitions file exists
    if [ -f "/etc/flightctl/definitions/telemetry-gateway.defs" ]; then
        local config_file="/etc/flightctl/service-config.yaml"
        local templates_dir="/opt/flightctl-observability/templates"
        local definitions_file="/etc/flightctl/definitions/telemetry-gateway.defs"
        
        # Source shared logic and call rendering with otel-collector specific definitions
        if [ -f "/etc/flightctl/scripts/render-templates.sh" ]; then
            if ! source /etc/flightctl/scripts/render-templates.sh; then
                log "ERROR" "Failed to source render-templates.sh"
                exit 1
            fi
            
            if ! render_templates "$config_file" "$templates_dir" "$definitions_file"; then
                log "ERROR" "Failed to render OpenTelemetry collector configuration"
                exit 1
            fi
            log "INFO" "OpenTelemetry collector configuration rendered successfully"
            
            # Setup certificates for telemetry-gateway after configuration is rendered
            setup_telemetry_gateway_certs
        else
            log "ERROR" "render-templates.sh not found"
            exit 1
        fi
    else
        log "INFO" "OpenTelemetry collector not installed, skipping"
    fi
}

setup_telemetry_gateway_certs() {
    log "INFO" "Setting up telemetry-gateway certificates..."
    
    # Check if certificate setup script exists
    if [ -f "/etc/flightctl/scripts/setup_telemetry_gateway_certs.sh" ]; then
        # Telemetry-gateway always uses Podman mode
        local mode="podman"

        log "INFO" "Running certificate setup in $mode mode..."

        local sans="DNS:localhost,DNS:flightctl-telemetry-gateway,IP:127.0.0.1"
        # Source the functions file to get get_ext_ip function
        if [ -f "/etc/flightctl/scripts/functions" ]; then
            source /etc/flightctl/scripts/functions
            local ext_ip=$(get_ext_ip)
            if [ -n "$ext_ip" ]; then
                sans="${sans},DNS:telemetry-gateway.${ext_ip}.nip.io"
            fi
        fi

        # Run the certificate setup script
        if ! /etc/flightctl/scripts/setup_telemetry_gateway_certs.sh --mode "$mode" \
        --sans "$sans" --force-rotate  ; then
            log "ERROR" "Certificate setup failed, aborting configuration rendering"
            exit 1
        else
            log "INFO" "Telemetry-gateway certificates setup completed successfully"
        fi
    else
        log "WARNING" "Certificate setup script not found at /etc/flightctl/scripts/setup_telemetry_gateway_certs.sh"
        log "INFO" "Certificates will need to be set up manually"
    fi
}

main() {
    log "INFO" "Starting FlightCtl observability configuration rendering..."
    
    check_prerequisites
    render_observability_config
    render_telemetry_gateway_config
    
    log "INFO" "FlightCtl observability configuration rendering completed successfully!"
    echo ""
    echo "Configuration has been updated. To start/restart services, use:"
    echo "  sudo systemctl start flightctl-observability.target      # Full stack"
    echo "  sudo systemctl start flightctl-telemetry-gateway.target     # OpenTelemetry collector only"
    echo ""
    echo "To stop services, use:"
    echo "  sudo systemctl stop flightctl-observability.target       # Full stack"
    echo "  sudo systemctl stop flightctl-telemetry-gateway.target      # OpenTelemetry collector only"
}

# Show usage if help is requested
if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
    cat << EOF
FlightCtl Observability Configuration Renderer

USAGE:
    $0 [OPTIONS]

DESCRIPTION:
    Renders observability configuration templates from /etc/flightctl/service-config.yaml,
    sets up telemetry-gateway certificates, and reloads systemd daemon. Does NOT start or stop services.

    This script supports both full observability stack and standalone OpenTelemetry 
    collector installations.

    This script will:
    1. Check prerequisites based on installed components
    2. Render observability configuration templates (if full stack is installed)
    3. Render OpenTelemetry collector configuration (if installed)
    4. Setup telemetry-gateway certificates (if telemetry-gateway is installed)
    5. Reload systemd daemon

    To start/stop services after rendering, use systemd targets:
    - flightctl-observability.target (full stack)
    - flightctl-telemetry-gateway.target (OpenTelemetry collector only)

OPTIONS:
    -h, --help    Show this help message

EXAMPLES:
    # Render configuration
    $0

    # Start services after rendering
    systemctl start flightctl-observability.target

    # Stop services
    systemctl stop flightctl-observability.target

EOF
    exit 0
fi

main "$@" 