/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.channel.cc.orchestrator.mixdec.domain.services;

import java.time.Duration;
import java.util.List;

import javax.ejb.Stateless;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;

import com.scytl.products.ov.channel.cc.orchestrator.commons.infrastructure.persistence.Jdbc;
import com.scytl.products.ov.channel.cc.orchestrator.commons.infrastructure.persistence.PartialResultsRepository;
import com.scytl.products.ov.channel.cc.orchestrator.commons.messaging.ResultsReadyListener;
import com.scytl.products.ov.channel.cc.orchestrator.commons.polling.PollingService;
import com.scytl.products.ov.channel.cc.orchestrator.commons.polling.PollingServiceImpl;
import com.scytl.products.ov.channel.cc.orchestrator.commons.polling.ReactivePartialResultsHandlerImpl;
import com.scytl.products.ov.channel.cc.orchestrator.commons.polling.ReactiveResultsHandler;
import com.scytl.products.ov.commons.messaging.MessageListener;

@Stateless
public class MixDecBeanProducer {

    private static final Duration KEY_GENERATION_POLLING_TIMEOUT =
        getDuration("mixing_key_generation_polling_timeout_ms", Duration.ofMillis(20000));

    private static final Duration KEY_GENERATION_INTER_POLLS_DELAY =
        getDuration("mixing_key_generation_inter_polls_delay_ms", Duration.ofMillis(100));

    private static Duration getDuration(String propertyName, Duration defaultValue) {
        String propertyValue = System.getProperty(propertyName);
        if (propertyValue == null) {
            return defaultValue;
        }
        return Duration.ofMillis(Long.parseLong(propertyValue));
    }

    @Produces
    @ApplicationScoped
    @MixDecKeyGeneration
    public ReactiveResultsHandler<List<byte[]>> keyGenerationResultsHandler(
            @Jdbc PartialResultsRepository<byte[]> repository) {
        Duration timeout = KEY_GENERATION_POLLING_TIMEOUT.multipliedBy(2);
        ReactivePartialResultsHandlerImpl<byte[]> handler =
            new ReactivePartialResultsHandlerImpl<>(repository, timeout);
        handler.start();
        return handler;
    }

    public void stopKeyGenerationResultsHandler(
            @Disposes @MixDecKeyGeneration ReactiveResultsHandler<List<byte[]>> handler) {
        ((ReactivePartialResultsHandlerImpl<byte[]>) handler).stop();
    }

    @Produces
    @MixDecKeyGeneration
    public PollingService<List<byte[]>> keyGenerationPollingService(
            @MixDecKeyGeneration ReactiveResultsHandler<List<byte[]>> handler) {
        return new PollingServiceImpl<>(handler, KEY_GENERATION_POLLING_TIMEOUT, KEY_GENERATION_INTER_POLLS_DELAY);
    }

    @Produces
    @MixDecKeyGeneration
    @ResultsReady
    public MessageListener keyGenerationResultsReadyListener(
            @MixDecKeyGeneration ReactiveResultsHandler<List<byte[]>> handler) {
        return new ResultsReadyListener(handler);
    }
}
