package meerkat.voting.controller.callbacks;

import meerkat.protobuf.Voting.UIElement;
import meerkat.voting.controller.commands.*;
import meerkat.voting.gui.ui.VotingBoothUI.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * A controller callback for the cast-or-audit request to the UI.
 * Upon getting a FinalizeBallotChoice response from the voter, the callback then registers a new command
 * to the controller queue, either a CastCommand or an AuditCommand according to the voter's choice
 */
public class CastOrAuditCallback extends ControllerCallback<FinalizeBallotChoice> {
    protected final static Logger logger = LoggerFactory.getLogger(CastOrAuditCallback.class);
    protected final UIElement unrecognizedFinalizeResponseMessage;

    public CastOrAuditCallback(int requestId,
                               long ballotSerialNumber,
                               LinkedBlockingQueue<ControllerCommand> controllerQueue,
                               UIElement unrecognizedFinalizeResponseMessage) {
        super(requestId, ballotSerialNumber, controllerQueue);
        this.unrecognizedFinalizeResponseMessage = unrecognizedFinalizeResponseMessage;
    }

    @Override
    public void onSuccess(FinalizeBallotChoice result) {
        if (result == FinalizeBallotChoice.CAST) {
            enqueueCommand(new CastCommand(getRequestIdentifier(), getBallotSerialNumber()));
        }
        else if (result == FinalizeBallotChoice.AUDIT) {
            enqueueCommand(new AuditCommand(getRequestIdentifier(), getBallotSerialNumber()));
        }
        else {
            logger.error("CastOrAuditCallback got an unrecognized response: " + result);
            onFailure(new IllegalArgumentException("CastOrAuditCallback got an unknown result (" + result + ")"));
        }

    }

    @Override
    public void onFailure(Throwable t) {
        logger.error("CastOrAuditCallback got a failure: " + t);
        enqueueCommand(new ReportErrorCommand(getRequestIdentifier(),
                getBallotSerialNumber(),
                unrecognizedFinalizeResponseMessage));
    }
}



