package ru.yandex.webmaster3.core.worker.client;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import ru.yandex.webmaster3.core.logbroker.writer.LogbrokerRoundRobinParitionClient;
import ru.yandex.webmaster3.core.security.tvm.TVMTokenService;
import ru.yandex.webmaster3.core.worker.task.WorkerTaskPriority;

/**
 * ishalaru
 * 27.11.2019
 **/
@Slf4j
@Service("logBrokerMultiTopicClient")
public class LogbrokerMultiTopicClient {
    private final TVMTokenService tvmTokenService;
    private final String host;
    private final int port;
    private final String topicPrefix;
    private final String hostName;
    private final int paritionCount;
    private Map<WorkerTaskPriority, LogbrokerRoundRobinParitionClient> logbrokerClientMap;

    @Autowired
    public LogbrokerMultiTopicClient(
            @Qualifier("logBrokerTvmTokenService") TVMTokenService tvmTokenService,
            @Value("${webmaster3.core.logBrokerHost}") String host,
            @Value("${webmaster3.core.logBrokerPort:2135}") int port,
            @Value("${webmaster3.core.logbroker.task.topic.prefix}") String topicPrefix,
            @Value("${application.hostname}") String hostName,
            @Value("${webmaster3.core.logbroker.task.partition.count:3}") int paritionCount) {
        this.tvmTokenService = tvmTokenService;
        this.host = host;
        this.port = port;
        this.topicPrefix = topicPrefix;
        this.hostName = hostName;
        this.paritionCount = paritionCount;
    }

    @PostConstruct
    public void init() {
        logbrokerClientMap = new EnumMap<>(WorkerTaskPriority.class);
        for (WorkerTaskPriority value : WorkerTaskPriority.values()) {
            String topic = topicPrefix + "-" + value.name().toLowerCase();
            LogbrokerRoundRobinParitionClient logbrokerClient = new LogbrokerRoundRobinParitionClient(tvmTokenService, topic, hostName, host, port, paritionCount);
            logbrokerClient.init();
            logbrokerClientMap.put(value, logbrokerClient);
        }
    }

    public boolean write(List<byte[]> value, WorkerTaskPriority priority) {
        try {
            logbrokerClientMap
                    .getOrDefault(priority, logbrokerClientMap.get(WorkerTaskPriority.NORMAL))
                    .write(value);
        } catch (Exception exp) {
            log.error("Can't send message to workers.", exp);
            return false;
        }
        return true;
    }

    public boolean write(String value, WorkerTaskPriority priority) {
        try {
            logbrokerClientMap
                    .getOrDefault(priority, logbrokerClientMap.get(WorkerTaskPriority.NORMAL))
                    .write(value.getBytes());
        } catch (Exception exp) {
            log.error("Can't send message to workers.", exp);
            return false;
        }
        return true;
    }

}
