/*
 * Copyright 2018-2023 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.opencord.kafka.impl;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.kafka.common.KafkaException;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;
import org.onosproject.cluster.ClusterService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.basics.SubjectFactories;
import org.opencord.kafka.EventBusService;
import org.slf4j.Logger;

import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newScheduledThreadPool;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Sends events to a Kafka event bus.
 */
@Component(immediate = true)
public class KafkaIntegration implements EventBusService {

    private final Logger log = getLogger(getClass());
    private static final Class<KafkaConfig>
            KAFKA_CONFIG_CLASS = KafkaConfig.class;

    protected static final String APP_NAME = "org.opencord.kafka";
    private ApplicationId appId;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected NetworkConfigRegistry configRegistry;

    private static StringSerializer stringSerializer = new StringSerializer();

    private AtomicReference<KafkaProducer<String, String>> kafkaProducerRef = new AtomicReference<>();

    private InternalNetworkConfigListener configListener =
            new InternalNetworkConfigListener();

    private final ExecutorService executor = newSingleThreadExecutor(
            groupedThreads(this.getClass().getSimpleName(), "events", log));
    private final ScheduledExecutorService scheduledExecutorService = newScheduledThreadPool(1,
            groupedThreads(this.getClass().getSimpleName(), "kafka", log));
    ScheduledFuture producerCreate;

    private ConfigFactory<ApplicationId, KafkaConfig> kafkaConfigFactory =
            new ConfigFactory<ApplicationId, KafkaConfig>(
                    SubjectFactories.APP_SUBJECT_FACTORY, KAFKA_CONFIG_CLASS,
                    "kafka") {
                @Override
                public KafkaConfig createConfig() {
                    return new KafkaConfig();
                }
            };

    private static final String CLIENT_ID = "client.id";
    private static final String BOOTSTRAP_SERVERS = "bootstrap.servers";
    private static final String RETRIES = "retries";
    private static final String RECONNECT_BACKOFF = "reconnect.backoff.ms";
    private static final String INFLIGHT_REQUESTS =
            "max.in.flight.requests.per.connection";
    private static final String ACKS = "acks";
    private static final String KEY_SERIALIZER = "key.serializer";
    private static final String VALUE_SERIALIZER = "value.serializer";
    private static final String STRING_SERIALIZER =
            stringSerializer.getClass().getCanonicalName();

    private static final String TIMESTAMP = "timestamp";

    @Activate
    public void activate() {
        appId = coreService.registerApplication(APP_NAME);
        configRegistry.registerConfigFactory(kafkaConfigFactory);
        configRegistry.addListener(configListener);
        configure();

        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        configRegistry.removeListener(configListener);
        configRegistry.unregisterConfigFactory(kafkaConfigFactory);

        executor.shutdownNow();

        shutdownKafka();
        log.info("Stopped");
    }

    private void configure() {
        KafkaConfig config =
                configRegistry.getConfig(appId, KAFKA_CONFIG_CLASS);
        if (config == null) {
            log.info("Kafka configuration not present");
            return;
        }
        configure(config);
    }

    private void configure(KafkaConfig config) {
        checkNotNull(config);

        Properties properties = new Properties();
        properties.put(CLIENT_ID, clusterService.getLocalNode().id().toString());
        properties.put(BOOTSTRAP_SERVERS, config.getBootstrapServers());
        properties.put(RETRIES, config.getRetries());
        properties.put(RECONNECT_BACKOFF, config.getReconnectBackoff());
        properties.put(INFLIGHT_REQUESTS, config.getInflightRequests());
        properties.put(ACKS, config.getAcks());
        properties.put(KEY_SERIALIZER, STRING_SERIALIZER);
        properties.put(VALUE_SERIALIZER, STRING_SERIALIZER);
        log.info("configured properties {}", properties);
        startKafka(properties);
    }

    private void unconfigure() {
        shutdownKafka();
    }

    private synchronized void startKafka(Properties properties) {
        if (kafkaProducerRef.get() == null) {
            // Kafka client doesn't play nice with the default OSGi classloader
            // This workaround temporarily changes the thread's classloader so that
            // the Kafka client can load the serializer classes.
            ClassLoader original = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
            try {
                log.info("Starting Kafka producer");
                try {
                    KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);
                    kafkaProducerRef.set(kafkaProducer);
                } catch (KafkaException e) {
                    log.error("Unable to create the kafka producer", e);
                    // Try again in a little bit
                    producerCreate = scheduledExecutorService.schedule(() -> configure(), 30, TimeUnit.SECONDS);
                }
            } finally {
                Thread.currentThread().setContextClassLoader(original);
            }
        }
    }

    private synchronized void shutdownKafka() {
        if (producerCreate != null) {
            producerCreate.cancel(true);
            producerCreate = null;
        }

        if (kafkaProducerRef.get() != null) {
            KafkaProducer<String, String> kafkaProducer = kafkaProducerRef.get();

            kafkaProducerRef.set(null);

            log.info("Shutting down Kafka producer");
            kafkaProducer.flush();
            kafkaProducer.close(0, TimeUnit.MILLISECONDS);
        }
    }

    private void logException(Exception e) {
        if (e != null) {
            log.error("Exception while sending to Kafka", e);
        }
    }

    @Override
    public void send(String topic, JsonNode data) {
        KafkaProducer<String, String> producer = kafkaProducerRef.get();
        if (producer == null) {
            log.warn("Not sending event as kafkaProducer is not defined: {}", data.toString());
            return;
        }

        if (log.isTraceEnabled()) {
            log.trace("Sending event to Kafka: {}", data.toString());
        }

        try {
            producer.send(new ProducerRecord<>(topic, data.toString()),
                    (r, e) -> logException(e));
        } catch (KafkaException e) {
            log.warn("Sending to kafka failed", e);
        }
    }

    private class InternalNetworkConfigListener implements NetworkConfigListener {

        @Override
        public void event(NetworkConfigEvent event) {
            log.info("Event type {}", event.type());
            switch (event.type()) {
            case CONFIG_ADDED:
            case CONFIG_UPDATED:
                unconfigure();
                configure((KafkaConfig) event.config().get());
                break;
            case CONFIG_REMOVED:
                unconfigure();
                break;
            case CONFIG_REGISTERED:
            case CONFIG_UNREGISTERED:
            default:
                break;
            }
        }

        @Override
        public boolean isRelevant(NetworkConfigEvent event) {
            return event.configClass().equals(KAFKA_CONFIG_CLASS);
        }
    }
}
