#!/usr/bin/env bash

# Prometheus Configuration Validator
# Validates Prometheus configurations, alert rules, and recording rules using promtool
# Last Updated: January 2025

set -euo pipefail

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

print_info() { echo -e "${BLUE}ℹ${NC} $1"; }
print_success() { echo -e "${GREEN}✓${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
print_error() { echo -e "${RED}✗${NC} $1"; }

print_header() {
    echo ""
    echo "═══════════════════════════════════════════════════════════════"
    echo "   Prometheus Configuration Validator"
    echo "═══════════════════════════════════════════════════════════════"
    echo ""
}

# Check if promtool is installed
check_promtool() {
    if ! command -v promtool &> /dev/null; then
        print_error "promtool not found"
        echo ""
        echo "Install promtool:"
        echo "  - Download Prometheus: https://prometheus.io/download/"
        echo "  - Or use Docker: alias promtool='docker run --rm -v \$(pwd):/config prom/prometheus:latest promtool'"
        echo ""
        exit 1
    fi
    print_success "promtool found: $(promtool --version | head -1)"
}

# Validate Prometheus configuration
validate_config() {
    local config_file="$1"

    if [ ! -f "$config_file" ]; then
        print_error "Configuration file not found: $config_file"
        return 1
    fi

    print_info "Validating configuration: $config_file"

    if promtool check config "$config_file" 2>&1 | tee /tmp/promtool-output.txt; then
        print_success "Configuration is valid"
        return 0
    else
        print_error "Configuration validation failed"
        cat /tmp/promtool-output.txt
        return 1
    fi
}

# Validate alert rules
validate_alert_rules() {
    local rules_dir="${1:-alerting-rules}"

    if [ ! -d "$rules_dir" ]; then
        print_warning "Alert rules directory not found: $rules_dir"
        return 0
    fi

    print_info "Validating alert rules in: $rules_dir"

    local found_rules=false
    local all_valid=true

    for rule_file in "$rules_dir"/*.yml "$rules_dir"/*.yaml; do
        if [ -f "$rule_file" ]; then
            found_rules=true
            echo ""
            print_info "  Checking: $(basename "$rule_file")"

            if promtool check rules "$rule_file"; then
                print_success "  Valid: $(basename "$rule_file")"
            else
                print_error "  Invalid: $(basename "$rule_file")"
                all_valid=false
            fi
        fi
    done

    if [ "$found_rules" = false ]; then
        print_warning "No alert rule files found"
        return 0
    fi

    if [ "$all_valid" = true ]; then
        print_success "All alert rules are valid"
        return 0
    else
        print_error "Some alert rules are invalid"
        return 1
    fi
}

# Validate recording rules
validate_recording_rules() {
    local rules_dir="${1:-recording-rules}"

    if [ ! -d "$rules_dir" ]; then
        print_warning "Recording rules directory not found: $rules_dir"
        return 0
    fi

    print_info "Validating recording rules in: $rules_dir"

    local found_rules=false
    local all_valid=true

    for rule_file in "$rules_dir"/*.yml "$rules_dir"/*.yaml; do
        if [ -f "$rule_file" ]; then
            found_rules=true
            echo ""
            print_info "  Checking: $(basename "$rule_file")"

            if promtool check rules "$rule_file"; then
                print_success "  Valid: $(basename "$rule_file")"
            else
                print_error "  Invalid: $(basename "$rule_file")"
                all_valid=false
            fi
        fi
    done

    if [ "$found_rules" = false ]; then
        print_warning "No recording rule files found"
        return 0
    fi

    if [ "$all_valid" = true ]; then
        print_success "All recording rules are valid"
        return 0
    else
        print_error "Some recording rules are invalid"
        return 1
    fi
}

# Check for common issues
check_common_issues() {
    local config_file="$1"

    print_info "Checking for common configuration issues..."

    # Check for scrape_timeout > scrape_interval
    if grep -q "scrape_timeout:" "$config_file"; then
        print_warning "Ensure scrape_timeout is less than scrape_interval"
    fi

    # Check for external_labels in global section
    if ! grep -A 5 "^global:" "$config_file" | grep -q "external_labels:"; then
        print_warning "Consider adding external_labels for multi-cluster setup"
    fi

    # Check for alertmanager configuration
    if ! grep -q "alerting:" "$config_file"; then
        print_warning "No alertmanager configuration found"
    fi

    # Check for rule_files
    if ! grep -q "rule_files:" "$config_file"; then
        print_warning "No rule_files configured"
    fi

    print_success "Common issues check complete"
}

# Usage information
usage() {
    echo "Usage: $0 <prometheus-config.yml> [alerting-rules-dir] [recording-rules-dir]"
    echo ""
    echo "Arguments:"
    echo "  prometheus-config.yml    Path to Prometheus configuration file (required)"
    echo "  alerting-rules-dir       Directory containing alert rules (default: alerting-rules)"
    echo "  recording-rules-dir      Directory containing recording rules (default: recording-rules)"
    echo ""
    echo "Examples:"
    echo "  $0 prometheus.yml"
    echo "  $0 prometheus.yml rules/alerting rules/recording"
    echo ""
}

# Main execution
main() {
    print_header

    # Check arguments
    if [ $# -lt 1 ]; then
        usage
        exit 1
    fi

    local config_file="$1"
    local alert_rules_dir="${2:-alerting-rules}"
    local recording_rules_dir="${3:-recording-rules}"

    # Check promtool
    check_promtool

    echo ""

    # Validate configuration
    local config_valid=true
    validate_config "$config_file" || config_valid=false

    echo ""

    # Validate alert rules
    local alert_rules_valid=true
    validate_alert_rules "$alert_rules_dir" || alert_rules_valid=false

    echo ""

    # Validate recording rules
    local recording_rules_valid=true
    validate_recording_rules "$recording_rules_dir" || recording_rules_valid=false

    echo ""

    # Check common issues
    check_common_issues "$config_file"

    echo ""
    echo "═══════════════════════════════════════════════════════════════"

    # Final result
    if [ "$config_valid" = true ] && [ "$alert_rules_valid" = true ] && [ "$recording_rules_valid" = true ]; then
        print_success "All validations passed!"
        echo ""
        print_info "Next steps:"
        echo "  1. Deploy configuration to Prometheus"
        echo "  2. Reload Prometheus: curl -X POST http://localhost:9090/-/reload"
        echo "  3. Check targets: http://localhost:9090/targets"
        echo "  4. Check alerts: http://localhost:9090/alerts"
        echo ""
        return 0
    else
        print_error "Validation failed"
        echo ""
        print_info "Fix the issues above and try again"
        echo ""
        return 1
    fi
}

# Run main
main "$@"
