package at.ac.tuwien.sbc.valesriegler.xvsm;


import at.ac.tuwien.sbc.valesriegler.common.Bill;
import at.ac.tuwien.sbc.valesriegler.common.Util;
import at.ac.tuwien.sbc.valesriegler.types.DeliveryGroupData;
import at.ac.tuwien.sbc.valesriegler.types.DeliveryStatus;
import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
import org.mozartspaces.core.ContainerReference;
import org.mozartspaces.core.MzsConstants;
import org.mozartspaces.core.TransactionReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

public class DeliveryGroupXVSM extends AbstractXVSMConnector {
    private static final Logger log = LoggerFactory.getLogger(DeliveryGroupXVSM.class);

    private final int pizzeriaSpacePort;
    private final int groupId;

    private final ContainerReference myContainer;

    public DeliveryGroupXVSM(int groupId, int pizzeriaSpacePort, String address) {
        super(pizzeriaSpacePort);
        this.groupId = groupId;
        this.pizzeriaSpacePort = pizzeriaSpacePort;


        myContainer = useContainerOfSpaceWithPort(address, Util.DELIVERY_CUSTOMERS_PORT);
        pizzeriaDeliveryContainer = useContainerOfSpaceWithPort(Util.PIZZERIA_DELIVERY, pizzeriaSpacePort);
    }

    public void waitForMyOrder() {
        getDefaultBuilder().setCref(myContainer).setSpaceAction(new SpaceAction() {
            @Override
            public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {

                final List<Serializable> entities = castEntries(entries);
                try {
                    for (Serializable entity : entities) {
                        if (entity instanceof Bill) {
                            Bill bill = ((Bill) entity);
                            if (bill.groupId == groupId) {

                                final DeliveryGroupData template = new DeliveryGroupData(groupId);
                                template.setDeliveryStatus(null);
                                final TransactionReference tx = getDefaultTransaction();
                                final DeliveryGroupData group = takeMatchingEntity(template, pizzeriaDeliveryContainer, tx, MzsConstants.RequestTimeout.INFINITE, "Cannot get the delivery order!");
                                group.setDeliveryStatus(DeliveryStatus.PAID);
                                sendItemsToContainer(Arrays.asList(group), pizzeriaDeliveryContainer, MzsConstants.RequestTimeout.DEFAULT, tx);
                                capi.commitTransaction(tx);

                                notificationMgr.shutdown();
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("Delivery group exception!");
                    e.printStackTrace();
                }

            }
        }).createSpaceListenerImpl();
    }
}
