package de.accso.flexinale.common.infrastructure.eventbus;

import de.accso.flexinale.common.shared_kernel.FlexinaleIllegalStateException;
import org.apache.kafka.clients.admin.AdminClient;
import org.apache.kafka.clients.admin.DescribeClusterOptions;

import java.util.Map;
import java.util.concurrent.ExecutionException;

import static de.accso.flexinale.common.infrastructure.eventbus.KafkaConfiguration.adminConfig;
import static de.accso.flexinale.common.infrastructure.eventbus.KafkaConfiguration.kafkaTimeoutInMs;

public final class KafkaAvailabilityChecker {

    // Kafka availability is checked intentionally in Spring init phase
    //   so the whole application (or test) won't start if no Kafka is available

    public KafkaAvailabilityChecker() {
        try {
            if (!isKafkaAvailable()) {
                // intentionally not written to Log as this is checked in init phase where not even a logger
                //   might be available yet.
                System.err.println("ERROR - Kafka is not available! Start Kafka before starting this application or test!");
                throw new FlexinaleIllegalStateException("Kafka is not available.");
            }
        }
        catch (Exception ex) {
            System.err.println("ERROR - Kafka is not available! Start Kafka before starting this application or test!");
            throw new FlexinaleIllegalStateException("Kafka is not available.", ex);
        }
    }

    @SuppressWarnings({"SameReturnValue", "BooleanMethodIsAlwaysInverted"})
    public boolean isKafkaAvailable() throws ExecutionException {
        Map<String, Object> kafkaAdminConfig = adminConfig();

        try (var adminClient = AdminClient.create( kafkaAdminConfig )) {
            adminClient.describeCluster(new DescribeClusterOptions().timeoutMs(kafkaTimeoutInMs)).nodes().get();
        }
        catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
        return true;
    }

/*
    public static void main(String[] args) throws ExecutionException {
        boolean kafkaAvailable = new KafkaAvailabilityChecker().isKafkaAvailable();
        if (kafkaAvailable) {
            System.out.println("All fine, Kafka is available");
        }
    }
*/
}
