package fucoin.actions.transaction;

import fucoin.supervisor.DistributedCommittedTransferRequest;
import fucoin.supervisor.SuperVisorImpl;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;

public class ActionPrepareDistributedCommittedTransferAnswer extends CoordinatorTransaction {

    private ActorRef source;
    private ActorRef target;
    private int amount;
    private boolean granted;
    private long timestamp;
    private long id;

    public ActionPrepareDistributedCommittedTransferAnswer(ActorRef source,
                                                           ActorRef target, int amount, long timestamp, boolean granted, long id) {
        this.source = source;
        this.target = target;
        this.amount = amount;
        this.granted = granted;
        this.timestamp = timestamp;
        this.id = id;
    }

    @Override
    protected void onAction(ActorRef sender, ActorRef self,
                            UntypedActorContext context, SuperVisorImpl superVisor) {

        superVisor.addLogMsg("granted?" + granted);

        DistributedCommittedTransferRequest request = superVisor.getRequest(id);

        // ignore unknown requests
        if (request == null){
            return;
        }

        if (granted) {

            int newCount = request.addPositiveAnswer(sender);

            if (newCount == superVisor.getKnownNeighbors().size()) {
                ActionCommitDistributedCommittedTransfer acdct = new ActionCommitDistributedCommittedTransfer(source, target, amount, true, timestamp, id, request.getObserver());
                superVisor.addTransactionLogMessageSuccess("Transfer of " + amount + " FUC from" + source.path().name() + " to " + target.path().name());
                for (ActorRef neighbor : request.getAnswers()) {
                    neighbor.tell(acdct, self);
                }
                superVisor.deleteRequest(request);
            }
        } else {
            //A client wants to rollback
                superVisor.addTransactionLogMessageFail("Client does not grant commit of " + amount + " FUC (" + source.path().name() + " -> " + target.path().name() + ")");
                ActionCommitDistributedCommittedTransfer acdct = new ActionCommitDistributedCommittedTransfer(source, target, amount, false, timestamp, id, request.getObserver());
                for (ActorRef neighbor : request.getAnswers()) {
                    neighbor.tell(acdct, self);
                }
        }
    }

}