/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.onosproject.openstacktelemetry.impl;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import org.onosproject.openstacktelemetry.api.FlowInfo;
import org.onosproject.openstacktelemetry.api.KafkaTelemetryAdminService;
import org.onosproject.openstacktelemetry.api.OpenstackTelemetryService;
import org.onosproject.openstacktelemetry.api.TelemetryCodec;
import org.onosproject.openstacktelemetry.api.TelemetryConfigService;
import org.onosproject.openstacktelemetry.api.config.KafkaTelemetryConfig;
import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Future;

import static org.onosproject.openstacktelemetry.api.Constants.KAFKA_SCHEME;
import static org.onosproject.openstacktelemetry.api.config.TelemetryConfig.ConfigType.KAFKA;
import static org.onosproject.openstacktelemetry.config.DefaultKafkaTelemetryConfig.fromTelemetryConfig;

/**
 * Kafka telemetry manager.
 */
@Component(immediate = true, service = KafkaTelemetryAdminService.class)
public class KafkaTelemetryManager implements KafkaTelemetryAdminService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private static final String CODEC_PREFIX = "org.onosproject.openstacktelemetry.codec.";

    private static final String BOOTSTRAP_SERVERS = "bootstrap.servers";
    private static final String RETRIES = "retries";
    private static final String ACKS = "acks";
    private static final String BATCH_SIZE = "batch.size";
    private static final String LINGER_MS = "linger.ms";
    private static final String MEMORY_BUFFER = "buffer.memory";
    private static final String KEY_SERIALIZER = "key.serializer";
    private static final String VALUE_SERIALIZER = "value.serializer";

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected OpenstackTelemetryService openstackTelemetryService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TelemetryConfigService telemetryConfigService;

    private Map<String, Producer<String, byte[]>> producers = Maps.newConcurrentMap();

    @Activate
    protected void activate() {

        openstackTelemetryService.addTelemetryService(this);

        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        stop();

        openstackTelemetryService.removeTelemetryService(this);

        log.info("Stopped");
    }

    @Override
    public void start() {
        telemetryConfigService.getConfigsByType(KAFKA).forEach(c -> {
            KafkaTelemetryConfig kafkaConfig = fromTelemetryConfig(c);

            if (kafkaConfig != null && !c.name().equals(KAFKA_SCHEME) && c.enabled()) {
                StringBuilder kafkaServerBuilder = new StringBuilder();
                kafkaServerBuilder.append(kafkaConfig.address());
                kafkaServerBuilder.append(":");
                kafkaServerBuilder.append(kafkaConfig.port());

                // Configure Kafka server properties
                Properties prop = new Properties();
                prop.put(BOOTSTRAP_SERVERS, kafkaServerBuilder.toString());
                prop.put(RETRIES, kafkaConfig.retries());
                prop.put(ACKS, kafkaConfig.requiredAcks());
                prop.put(BATCH_SIZE, kafkaConfig.batchSize());
                prop.put(LINGER_MS, kafkaConfig.lingerMs());
                prop.put(MEMORY_BUFFER, kafkaConfig.memoryBuffer());
                prop.put(KEY_SERIALIZER, kafkaConfig.keySerializer());
                prop.put(VALUE_SERIALIZER, kafkaConfig.valueSerializer());

                producers.put(c.name(), new KafkaProducer<>(prop));
            }
        });

        log.info("Kafka producer has Started");
    }

    @Override
    public void stop() {
        if (!producers.isEmpty()) {
            producers.values().forEach(Producer::close);
        }

        producers.clear();

        log.info("Kafka producer has Stopped");
    }

    @Override
    public void restart() {
        stop();
        start();
    }

    @Override
    public Set<Future<RecordMetadata>> publish(Set<FlowInfo> flowInfos) {

        if (producers == null || producers.isEmpty()) {
            log.debug("Kafka telemetry service has not been enabled!");
            return null;
        }

        log.debug("Send telemetry record to kafka server...");
        Set<Future<RecordMetadata>> futureSet = Sets.newHashSet();
        producers.forEach((k, v) -> {
            TelemetryConfig config = telemetryConfigService.getConfig(k);
            KafkaTelemetryConfig kafkaConfig =
                    fromTelemetryConfig(config);

            try {
                Class codecClazz = Class.forName(CODEC_PREFIX + kafkaConfig.codec());
                TelemetryCodec codec = (TelemetryCodec) codecClazz.newInstance();

                ByteBuffer buffer = codec.encode(flowInfos);
                ProducerRecord record = new ProducerRecord<>(
                        kafkaConfig.topic(), kafkaConfig.key(), buffer.array());
                futureSet.add(v.send(record));
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
                log.warn("Failed to send telemetry record due to {}", e);
            }
        });
        return futureSet;
    }

    @Override
    public boolean isRunning() {
        return !producers.isEmpty();
    }
}
