#\!/bin/bash

set -e
set -o pipefail

# Usage function
usage() {
    echo "Usage: wild-cluster-services-up [options] [service...]"
    echo ""
    echo "Install cluster services from generated setup files."
    echo ""
    echo "Arguments:"
    echo "  service             Specific service(s) to install (optional)"
    echo ""
    echo "Options:"
    echo "  -h, --help          Show this help message"
    echo "  --list              List available services"
    echo "  --dry-run           Show what would be installed without running"
    echo ""
    echo "Examples:"
    echo "  wild-cluster-services-up                    # Install all services"
    echo "  wild-cluster-services-up metallb traefik    # Install specific services"
    echo "  wild-cluster-services-up --list             # List available services"
    echo ""
    echo "Available services (when setup files exist):"
    echo "  metallb, longhorn, traefik, coredns, cert-manager,"
    echo "  externaldns, kubernetes-dashboard, nfs, docker-registry"
    echo ""
    echo "Requirements:"
    echo "  - Must be run from a wild-cloud directory"
    echo "  - Cluster services must be generated first (wild-cluster-services-generate)"
    echo "  - Kubernetes cluster must be running and kubectl configured"
}

# Parse arguments
DRY_RUN=false
LIST_SERVICES=false
SPECIFIC_SERVICES=()

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            usage
            exit 0
            ;;
        --list)
            LIST_SERVICES=true
            shift
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        -*)
            echo "Unknown option $1"
            usage
            exit 1
            ;;
        *)
            SPECIFIC_SERVICES+=("$1")
            shift
            ;;
    esac
done

# Initialize Wild Cloud environment
if [ -z "${WC_ROOT}" ]; then
    print "WC_ROOT is not set."
    exit 1
else
    source "${WC_ROOT}/scripts/common.sh"
    init_wild_env
fi

CLUSTER_SETUP_DIR="${WC_HOME}/setup/cluster-services"

# Check if cluster setup directory exists
if [ ! -d "$CLUSTER_SETUP_DIR" ]; then
    print_error "Cluster services setup directory not found: $CLUSTER_SETUP_DIR"
    print_info "Run 'wild-cluster-services-generate' first to generate setup files"
    exit 1
fi

# Function to get available services
get_available_services() {
    local services=()
    for service_dir in "$CLUSTER_SETUP_DIR"/*; do
        if [ -d "$service_dir" ] && [ -f "$service_dir/install.sh" ]; then
            services+=($(basename "$service_dir"))
        fi
    done
    echo "${services[@]}"
}

# List services if requested
if [ "$LIST_SERVICES" = true ]; then
    print_header "Available Cluster Services"
    AVAILABLE_SERVICES=($(get_available_services))
    
    if [ ${#AVAILABLE_SERVICES[@]} -eq 0 ]; then
        print_warning "No services found in $CLUSTER_SETUP_DIR"
        print_info "Run 'wild-cluster-services-generate' first"
    else
        print_info "Services available for installation:"
        for service in "${AVAILABLE_SERVICES[@]}"; do
            if [ -f "$CLUSTER_SETUP_DIR/$service/install.sh" ]; then
                print_success "  ✓ $service"
            else
                print_warning "  ✗ $service (install.sh missing)"
            fi
        done
    fi
    exit 0
fi

# =============================================================================
# CLUSTER SERVICES INSTALLATION
# =============================================================================

print_header "Cluster Services Installation"

# Check kubectl connectivity
if [ "$DRY_RUN" = false ]; then
    print_info "Checking Kubernetes cluster connectivity..."
    if ! kubectl cluster-info >/dev/null 2>&1; then
        print_error "kubectl is not configured or cluster is not accessible"
        print_info "Make sure your cluster is running and kubeconfig is set up"
        print_info "You can get kubeconfig with: talosctl kubeconfig"
        exit 1
    fi
    print_success "Cluster is accessible"
fi

# Get list of services to install
if [ ${#SPECIFIC_SERVICES[@]} -gt 0 ]; then
    SERVICES_TO_INSTALL=("${SPECIFIC_SERVICES[@]}")
    print_info "Installing specific services: ${SERVICES_TO_INSTALL[*]}"
else
    # Install all available services in a specific order for dependencies
    SERVICES_TO_INSTALL=(
        "metallb"
        "longhorn" 
        "traefik"
        "coredns"
        "cert-manager"
        "externaldns"
        "kubernetes-dashboard"
        "nfs"
        "docker-registry"
    )
    print_info "Installing all available services"
fi

# Filter to only include services that actually exist
EXISTING_SERVICES=()
for service in "${SERVICES_TO_INSTALL[@]}"; do
    if [ -d "$CLUSTER_SETUP_DIR/$service" ] && [ -f "$CLUSTER_SETUP_DIR/$service/install.sh" ]; then
        EXISTING_SERVICES+=("$service")
    elif [ ${#SPECIFIC_SERVICES[@]} -gt 0 ]; then
        # Only warn if user specifically requested this service
        print_warning "Service '$service' not found or missing install.sh"
    fi
done

if [ ${#EXISTING_SERVICES[@]} -eq 0 ]; then
    print_error "No installable services found"
    print_info "Run 'wild-cluster-services-generate' first to generate setup files"
    exit 1
fi

print_info "Services to install: ${EXISTING_SERVICES[*]}"

if [ "$DRY_RUN" = true ]; then
    print_info "DRY RUN - would install the following services:"
    for service in "${EXISTING_SERVICES[@]}"; do
        print_info "  - $service: $CLUSTER_SETUP_DIR/$service/install.sh"
    done
    exit 0
fi

# Install services
cd "$CLUSTER_SETUP_DIR"
INSTALLED_COUNT=0
FAILED_COUNT=0

for service in "${EXISTING_SERVICES[@]}"; do
    echo ""
    print_header "Installing $service"
    
    if [ -f "./$service/install.sh" ]; then
        print_info "Running $service installation..."
        if ./"$service"/install.sh; then
            print_success "$service installed successfully"
            INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
        else
            print_error "$service installation failed"
            FAILED_COUNT=$((FAILED_COUNT + 1))
        fi
    else
        print_warning "$service install script not found"
        FAILED_COUNT=$((FAILED_COUNT + 1))
    fi
done

cd - >/dev/null

# Summary
echo ""
print_header "Installation Summary"
print_success "Successfully installed: $INSTALLED_COUNT services"
if [ $FAILED_COUNT -gt 0 ]; then
    print_warning "Failed to install: $FAILED_COUNT services"
fi

if [ $INSTALLED_COUNT -gt 0 ]; then
    echo ""
    print_info "Next steps:"
    echo "  1. Verify installations with: kubectl get pods --all-namespaces"
    echo "  2. Check service status with: kubectl get services --all-namespaces"
    
    # Service-specific next steps
    if [[ " ${EXISTING_SERVICES[*]} " =~ " kubernetes-dashboard " ]]; then
        INTERNAL_DOMAIN=$(wild-config cloud.internalDomain 2>/dev/null || echo "your-internal-domain")
        echo "  3. Access dashboard at: https://dashboard.${INTERNAL_DOMAIN}"
        echo "  4. Get dashboard token with: ${WC_ROOT}/bin/dashboard-token"
    fi
    
    if [[ " ${EXISTING_SERVICES[*]} " =~ " cert-manager " ]]; then
        echo "  3. Check cert-manager: kubectl get clusterissuers"
    fi
fi

if [ $FAILED_COUNT -eq 0 ]; then
    print_success "All cluster services installed successfully!"
else
    print_warning "Some services failed to install. Check the output above for details."
    exit 1
fi