package ru.yandex.webmaster3.core.logbroker.reader;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PreDestroy;

import lombok.extern.slf4j.Slf4j;

import ru.yandex.kikimr.persqueue.consumer.internal.read.ReaderConfig;
import ru.yandex.webmaster3.core.security.tvm.TVMTokenService;

/**
 * ishalaru
 * 14.11.2019
 **/
@Slf4j
public class LogbrokerStreamConsumerBuilder {
    private final TVMTokenService tvmTokenService;
    private final List<String> endPoints;
    private ReaderConfig.Builder readerConfigBuilder;
    private List<LogbrokerStreamConsumer> logbrokerStreamConsumers;
    private List<LogbrokerSettings> processingSettings;

    public LogbrokerStreamConsumerBuilder(TVMTokenService tvmTokenService,
                                          List<String> endPoints,
                                          List<LogbrokerSettings> processingSettings) {
        this.tvmTokenService = tvmTokenService;
        this.processingSettings = processingSettings;
        this.endPoints = endPoints;
    }

    public LogbrokerStreamConsumerBuilder(TVMTokenService tvmTokenService,
                                          List<String> endPoints,
                                          String topic,
                                          String consumer,
                                          IDataProcessing dataProcessing) {
        this(tvmTokenService, endPoints, List.of(new LogbrokerSettings(dataProcessing, topic, consumer)));
    }

    public void init() {
        logbrokerStreamConsumers = new ArrayList<>(endPoints.size());
        for (var item : processingSettings) {
            init(item.getTopic(), item.getConsumer(), item.getDataProcessing(), logbrokerStreamConsumers);
        }
    }

    public void init(String topic, String consumePath, IDataProcessing dataProcessing, List<LogbrokerStreamConsumer> logbrokerStreamConsumers) {
        for (String endPoint : endPoints) {

            final LogbrokerStreamConsumer logbrokerStreamConsumer =
                    new LogbrokerStreamConsumer(tvmTokenService, endPoint, topic, consumePath, dataProcessing);
            if (readerConfigBuilder != null) {
                logbrokerStreamConsumer.setReaderConfigBuilder(readerConfigBuilder);
            }
            logbrokerStreamConsumers.add(logbrokerStreamConsumer);
        }
    }

    public void checkConnectionState() {
        log.trace("Start check state of logbroker stream consumers");
        for (LogbrokerStreamConsumer logbrokerStreamConsumer : logbrokerStreamConsumers) {
            try {
                logbrokerStreamConsumer.checkStateAndReInit();
            } catch (Throwable exp) {
                log.error(exp.getMessage(), exp);
            }
        }
        log.trace("End check state of logbroker stream consumers");
    }

    @PreDestroy
    public void destroy() {
        for (LogbrokerStreamConsumer logbrokerStreamConsumer : logbrokerStreamConsumers) {
            try {
                logbrokerStreamConsumer.close();
            } catch (Exception exp) {
                log.error(exp.getMessage(), exp);
            }
        }
    }

    public void setReaderConfigBuilder(ReaderConfig.Builder readerConfigBuilder) {
        this.readerConfigBuilder = readerConfigBuilder;
    }
}


