package meerkat.voting.controller.callbacks;

import meerkat.voting.controller.commands.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * This is quite a special callback. It is not issued in a normal flow of the voting.
 * This callback is made only for a request to the UI to choose handling of failure in encryption.
 * When encryption/signature fails the voter is asked in the UI whether to retry or abort.
 * This specific callback decides, upon the answer to this request, which command to register in the controller's queue
 */
public class EncryptionFailedCallback extends ControllerCallback<Integer> {
    protected final static Logger logger = LoggerFactory.getLogger(EncryptionFailedCallback.class);

    public EncryptionFailedCallback(int requestId,
                                    long ballotSerialNumber,
                                    LinkedBlockingQueue<ControllerCommand> controllerQueue) {
        super(requestId, ballotSerialNumber, controllerQueue);
    }

    @Override
    public void onSuccess(Integer result) {
        logger.debug("callback for encryption-failed request is initiated successfully");
        int res = result.intValue();
        if (res == 0) {
            logger.debug("voter chose to retry encryption");
            enqueueCommand(new RetryEncryptAndCommitBallotCommand(getRequestIdentifier(), getBallotSerialNumber()));
        }
        else if (res == 1) {
            logger.debug("voter chose to abort the vote");
            enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
        }
        else {
            onFailure(new IllegalArgumentException("EncryptionFailedCallback got an unknown result (" + res + ")"));
        }
    }

    @Override
    public void onFailure(Throwable t) {
        logger.error("Error message execution initiated a failure: " + t);
        enqueueCommand(new RestartVotingCommand(getRequestIdentifier(), getBallotSerialNumber()));
    }
}
