#!/bin/bash

# Extract MongoDB TLS certificates from the mongo-tls secret in hubble-system namespace.
# Decodes and writes ca.crt, tls.crt, tls.key, and tls-combined.pem to an output directory.

set -euo pipefail

KUBECONFIG_FILE=""
OUTPUT_DIR="./mongo-tls-certs"
SECRET_NAME="${SECRET_NAME:-mongo-tls}"
NAMESPACE="${NAMESPACE:-hubble-system}"

CERT_KEYS=(ca.crt tls.crt tls.key tls-combined.pem)

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

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

show_help() {
    cat << EOF
Extract MongoDB TLS Certificates

Extracts and decodes TLS certificate files from the mongo-tls secret in hubble-system.

Usage: $0 [OPTIONS]

OPTIONS:
    --kubeconfig FILE    Path to kubeconfig file (optional, uses default if not provided)
    --output-dir DIR     Output directory for certificate files (default: ./mongo-tls-certs)
    --help               Show this help message

OUTPUT FILES:
    ca.crt               MongoDB CA certificate
    tls.crt              MongoDB server certificate
    tls.key              MongoDB server private key
    tls-combined.pem     Combined certificate and key

EXAMPLES:
    $0 --kubeconfig /path/to/kubeconfig
    $0 --kubeconfig ./vertex.kubeconfig --output-dir ./bk1/mongo-tls
EOF
}

parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --kubeconfig)
                KUBECONFIG_FILE="$2"
                shift 2
                ;;
            --output-dir)
                OUTPUT_DIR="$2"
                shift 2
                ;;
            --help)
                show_help
                exit 0
                ;;
            *)
                log_error "Unknown option: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

validate_parameters() {
    if [[ -n "$KUBECONFIG_FILE" && ! -f "$KUBECONFIG_FILE" ]]; then
        log_error "kubeconfig file does not exist: $KUBECONFIG_FILE"
        exit 1
    fi
}

kubectl_cmd() {
    if [[ -n "$KUBECONFIG_FILE" ]]; then
        kubectl --kubeconfig="$KUBECONFIG_FILE" "$@"
    else
        kubectl "$@"
    fi
}

check_dependencies() {
    if ! command -v kubectl &>/dev/null; then
        log_error "kubectl command not found. Please install kubectl."
        exit 1
    fi
    if ! command -v base64 &>/dev/null; then
        log_error "base64 command not found. Please install base64."
        exit 1
    fi
}

test_cluster_connection() {
    log_info "Testing cluster connectivity..."
    if ! kubectl_cmd cluster-info &>/dev/null; then
        log_error "Failed to connect to cluster. Please check your kubeconfig and cluster status."
        exit 1
    fi
    log_success "Cluster connection successful"
}

create_output_directory() {
    log_info "Creating output directory: $OUTPUT_DIR"
    mkdir -p "$OUTPUT_DIR"
    log_success "Output directory ready: $OUTPUT_DIR"
}

extract_cert() {
    local key="$1"
    local output_file="$OUTPUT_DIR/$key"

    log_info "Extracting $key from secret $SECRET_NAME..."

    local encoded
    encoded=$(kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE" -o "go-template={{index .data \"${key}\"}}" 2>/dev/null || true)

    if [[ -z "$encoded" ]]; then
        log_error "Key '$key' not found in secret '$SECRET_NAME'"
        log_info "Available keys in the secret:"
        kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE" -o jsonpath='{range $k, $v := .data}{$k}{"\n"}{end}' 2>/dev/null || true
        exit 1
    fi

    if ! printf '%s' "$encoded" | base64 -d >"$output_file" 2>/dev/null; then
        log_error "Failed to decode base64 content for '$key'"
        exit 1
    fi

    if [[ "$key" == *.key || "$key" == *combined.pem ]]; then
        chmod 600 "$output_file"
    else
        chmod 644 "$output_file"
    fi

    log_success "Wrote $output_file"
}

main() {
    parse_arguments "$@"
    validate_parameters
    check_dependencies
    test_cluster_connection

    log_info "Checking secret $SECRET_NAME in namespace $NAMESPACE..."
    if ! kubectl_cmd get secret "$SECRET_NAME" -n "$NAMESPACE" &>/dev/null; then
        log_error "Secret '$SECRET_NAME' not found in namespace '$NAMESPACE'"
        exit 1
    fi

    create_output_directory

    for key in "${CERT_KEYS[@]}"; do
        extract_cert "$key"
    done

    log_success "MongoDB TLS certificate extraction completed successfully!"
    log_info "Certificate files:"
    ls -la "$OUTPUT_DIR"
}

main "$@"
