#!/bin/bash

# ============================================================================
# Kubernetes Infrastructure Monitoring Deployment Script
# ============================================================================
# Deploys kube-state-metrics and node-exporter for Kubernetes infrastructure
# monitoring in SigNoz
# ============================================================================

set -e

# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Configuration
NAMESPACE="bakery-ia"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Function to display help
show_help() {
    echo "Usage: $0 [OPTIONS] [COMMAND]"
    echo ""
    echo "Deploy Kubernetes infrastructure monitoring components"
    echo ""
    echo "Commands:"
    echo "  install     Install kube-state-metrics and node-exporter (default)"
    echo "  upgrade     Upgrade existing deployments"
    echo "  uninstall   Remove all infrastructure monitoring components"
    echo "  status      Show deployment status"
    echo ""
    echo "Options:"
    echo "  -h, --help          Show this help message"
    echo "  -d, --dry-run       Show what would be done without executing"
    echo "  -n, --namespace NS  Specify namespace (default: bakery-ia)"
    echo "  --microk8s          Use microk8s helm3 command (for MicroK8s clusters)"
    echo ""
    echo "Examples:"
    echo "  $0 install                    # Install on standard k8s"
    echo "  $0 --microk8s install         # Install on MicroK8s"
    echo "  $0 --microk8s upgrade         # Upgrade on MicroK8s"
    echo "  $0 --microk8s uninstall       # Remove from MicroK8s"
    echo "  $0 status                     # Check deployment status"
}

# Parse arguments
DRY_RUN=false
USE_MICROK8S=false
COMMAND="install"

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -d|--dry-run)
            DRY_RUN=true
            shift
            ;;
        -n|--namespace)
            NAMESPACE="$2"
            shift 2
            ;;
        --microk8s)
            USE_MICROK8S=true
            shift
            ;;
        install|upgrade|uninstall|status)
            COMMAND="$1"
            shift
            ;;
        *)
            echo -e "${RED}Unknown argument: $1${NC}"
            show_help
            exit 1
            ;;
    esac
done

# Set helm and kubectl commands based on environment
if [[ "$USE_MICROK8S" == true ]]; then
    HELM_CMD="microk8s helm3"
    KUBECTL_CMD="microk8s kubectl"
else
    HELM_CMD="helm"
    KUBECTL_CMD="kubectl"
fi

# Function to check prerequisites
check_prerequisites() {
    echo -e "${BLUE}Checking prerequisites...${NC}"

    # Check helm
    if [[ "$USE_MICROK8S" == true ]]; then
        # Test if microk8s helm3 command works directly
        if ! microk8s helm3 version &> /dev/null; then
            echo -e "${RED}Error: MicroK8s helm3 addon is not working.${NC}"
            echo "Enable it with: microk8s enable helm3"
            exit 1
        fi
        echo -e "${GREEN}MicroK8s helm3 is available.${NC}"
    else
        if ! command -v helm &> /dev/null; then
            echo -e "${RED}Error: Helm is not installed.${NC}"
            exit 1
        fi
    fi

    # Check kubectl connectivity
    if ! $KUBECTL_CMD cluster-info &> /dev/null; then
        echo -e "${RED}Error: Cannot connect to Kubernetes cluster.${NC}"
        exit 1
    fi

    echo -e "${GREEN}Prerequisites check passed.${NC}"
    echo ""
}

# Function to setup Helm repository
setup_helm_repo() {
    echo -e "${BLUE}Setting up Prometheus Community Helm repository...${NC}"

    if [[ "$DRY_RUN" == true ]]; then
        echo "  (dry-run) Would add prometheus-community Helm repository"
        return
    fi

    if $HELM_CMD repo list 2>/dev/null | grep -q "prometheus-community"; then
        echo -e "${BLUE}Repository already added, updating...${NC}"
        $HELM_CMD repo update prometheus-community
    else
        $HELM_CMD repo add prometheus-community https://prometheus-community.github.io/helm-charts
        $HELM_CMD repo update
    fi

    echo -e "${GREEN}Helm repository ready.${NC}"
    echo ""
}

# Function to ensure namespace exists
ensure_namespace() {
    echo -e "${BLUE}Ensuring namespace $NAMESPACE exists...${NC}"

    if [[ "$DRY_RUN" == true ]]; then
        echo "  (dry-run) Would create namespace if needed"
        return
    fi

    if ! $KUBECTL_CMD get namespace "$NAMESPACE" &> /dev/null; then
        $KUBECTL_CMD create namespace "$NAMESPACE"
        echo -e "${GREEN}Namespace $NAMESPACE created.${NC}"
    else
        echo -e "${BLUE}Namespace $NAMESPACE already exists.${NC}"
    fi
    echo ""
}

# Function to install kube-state-metrics
install_kube_state_metrics() {
    echo -e "${BLUE}Installing kube-state-metrics...${NC}"

    local values_file="$SCRIPT_DIR/kube-state-metrics-values.yaml"

    if [[ ! -f "$values_file" ]]; then
        echo -e "${RED}Error: Values file not found: $values_file${NC}"
        exit 1
    fi

    if [[ "$DRY_RUN" == true ]]; then
        echo "  (dry-run) Would install kube-state-metrics"
        echo "  Command: $HELM_CMD upgrade --install kube-state-metrics prometheus-community/kube-state-metrics -n $NAMESPACE -f $values_file"
        return
    fi

    $HELM_CMD upgrade --install kube-state-metrics \
        prometheus-community/kube-state-metrics \
        -n "$NAMESPACE" \
        -f "$values_file" \
        --wait \
        --timeout 5m

    echo -e "${GREEN}kube-state-metrics installed successfully.${NC}"
    echo ""
}

# Function to install node-exporter
install_node_exporter() {
    echo -e "${BLUE}Installing node-exporter...${NC}"

    local values_file="$SCRIPT_DIR/node-exporter-values.yaml"

    if [[ ! -f "$values_file" ]]; then
        echo -e "${RED}Error: Values file not found: $values_file${NC}"
        exit 1
    fi

    if [[ "$DRY_RUN" == true ]]; then
        echo "  (dry-run) Would install node-exporter"
        echo "  Command: $HELM_CMD upgrade --install node-exporter prometheus-community/prometheus-node-exporter -n $NAMESPACE -f $values_file"
        return
    fi

    $HELM_CMD upgrade --install node-exporter \
        prometheus-community/prometheus-node-exporter \
        -n "$NAMESPACE" \
        -f "$values_file" \
        --wait \
        --timeout 5m

    echo -e "${GREEN}node-exporter installed successfully.${NC}"
    echo ""
}

# Function to uninstall components
uninstall_components() {
    echo -e "${BLUE}Uninstalling Kubernetes infrastructure monitoring components...${NC}"

    if [[ "$DRY_RUN" == true ]]; then
        echo "  (dry-run) Would uninstall kube-state-metrics and node-exporter"
        return
    fi

    # Uninstall kube-state-metrics
    if $HELM_CMD list -n "$NAMESPACE" | grep -q "kube-state-metrics"; then
        echo -e "${BLUE}Removing kube-state-metrics...${NC}"
        $HELM_CMD uninstall kube-state-metrics -n "$NAMESPACE" --wait
        echo -e "${GREEN}kube-state-metrics removed.${NC}"
    else
        echo -e "${YELLOW}kube-state-metrics not found.${NC}"
    fi

    # Uninstall node-exporter
    if $HELM_CMD list -n "$NAMESPACE" | grep -q "node-exporter"; then
        echo -e "${BLUE}Removing node-exporter...${NC}"
        $HELM_CMD uninstall node-exporter -n "$NAMESPACE" --wait
        echo -e "${GREEN}node-exporter removed.${NC}"
    else
        echo -e "${YELLOW}node-exporter not found.${NC}"
    fi

    echo ""
}

# Function to show deployment status
show_status() {
    echo -e "${BLUE}=== Kubernetes Infrastructure Monitoring Status ===${NC}"
    echo ""

    echo -e "${BLUE}Helm Releases:${NC}"
    $HELM_CMD list -n "$NAMESPACE" | grep -E "(kube-state-metrics|node-exporter)" || echo "  No releases found"
    echo ""

    echo -e "${BLUE}Pods:${NC}"
    $KUBECTL_CMD get pods -n "$NAMESPACE" -l 'app.kubernetes.io/name in (kube-state-metrics, prometheus-node-exporter)' 2>/dev/null || echo "  No pods found"
    echo ""

    echo -e "${BLUE}Services:${NC}"
    $KUBECTL_CMD get svc -n "$NAMESPACE" | grep -E "(kube-state-metrics|node-exporter)" || echo "  No services found"
    echo ""

    echo -e "${BLUE}Endpoints (for SigNoz scraping):${NC}"
    echo "  kube-state-metrics: kube-state-metrics.$NAMESPACE.svc.cluster.local:8080"
    echo "  node-exporter:      node-exporter-prometheus-node-exporter.$NAMESPACE.svc.cluster.local:9100"
    echo ""
}

# Function to show post-install instructions
show_post_install_instructions() {
    echo -e "${BLUE}=== Post-Installation Instructions ===${NC}"
    echo ""
    echo "To enable SigNoz to scrape these metrics, update your SigNoz OTel Collector config."
    echo ""
    echo "Add the following to your signoz-values-prod.yaml under otelCollector.config:"
    echo ""
    cat << 'EOF'
otelCollector:
  config:
    receivers:
      prometheus:
        config:
          scrape_configs:
            - job_name: 'kube-state-metrics'
              static_configs:
                - targets: ['kube-state-metrics.bakery-ia.svc.cluster.local:8080']
              scrape_interval: 30s
            - job_name: 'node-exporter'
              static_configs:
                - targets: ['node-exporter-prometheus-node-exporter.bakery-ia.svc.cluster.local:9100']
              scrape_interval: 30s
    service:
      pipelines:
        metrics:
          receivers: [otlp, prometheus]
EOF
    echo ""
    echo "Then upgrade SigNoz:"
    if [[ "$USE_MICROK8S" == true ]]; then
        echo "  microk8s helm3 upgrade signoz signoz/signoz -n $NAMESPACE -f infrastructure/monitoring/signoz/signoz-values-prod.yaml"
    else
        echo "  helm upgrade signoz signoz/signoz -n $NAMESPACE -f infrastructure/monitoring/signoz/signoz-values-prod.yaml"
    fi
    echo ""
}

# Main execution
main() {
    echo -e "${BLUE}"
    echo "=========================================="
    echo "Kubernetes Infrastructure Monitoring"
    echo "=========================================="
    echo -e "${NC}"

    check_prerequisites

    case $COMMAND in
        install)
            setup_helm_repo
            ensure_namespace
            install_kube_state_metrics
            install_node_exporter
            show_status
            show_post_install_instructions
            echo -e "${GREEN}Installation completed successfully!${NC}"
            ;;
        upgrade)
            setup_helm_repo
            install_kube_state_metrics
            install_node_exporter
            show_status
            echo -e "${GREEN}Upgrade completed successfully!${NC}"
            ;;
        uninstall)
            uninstall_components
            echo -e "${GREEN}Uninstallation completed.${NC}"
            ;;
        status)
            show_status
            ;;
    esac
}

# Run main function
main
