package net.onrc.onos.core.newintent;

import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import net.onrc.onos.api.flowmanager.Flow;
import net.onrc.onos.api.flowmanager.FlowBatchHandle;
import net.onrc.onos.api.flowmanager.FlowBatchStateChangedEvent;
import net.onrc.onos.api.flowmanager.FlowId;
import net.onrc.onos.api.flowmanager.FlowManagerListener;
import net.onrc.onos.api.flowmanager.FlowManagerService;
import net.onrc.onos.api.flowmanager.FlowState;
import net.onrc.onos.api.flowmanager.FlowStateChange;
import net.onrc.onos.api.flowmanager.FlowStatesChangedEvent;
import net.onrc.onos.api.newintent.InstallableIntent;
import net.onrc.onos.api.newintent.Intent;
import net.onrc.onos.api.newintent.IntentInstaller;

import java.util.concurrent.CountDownLatch;

import static com.google.common.base.Preconditions.checkNotNull;
import static net.onrc.onos.api.flowmanager.FlowState.FAILED;
import static net.onrc.onos.api.flowmanager.FlowState.INSTALLED;
import static net.onrc.onos.api.flowmanager.FlowState.WITHDRAWN;

// TODO: consider naming because to call Flow manager's API will be removed
// in long-term refactoring
// TODO: consider unifying the install() and remove() by pulling up to this class
/**
 * Base class for implementing an intent installer, which use Flow Manager's API.
 *
 * @param <T> the type of intent
 */
public abstract class AbstractIntentInstaller<T extends InstallableIntent>
        implements IntentInstaller<T> {
    protected final FlowManagerService flowManager;

    /**
     * Constructs a base class with the specified Flow Manager service.
     *
     * @param flowManager Flow manager service, which is used to install/remove
     *                    an intent
     */
    protected AbstractIntentInstaller(FlowManagerService flowManager) {
        this.flowManager = flowManager;
    }

    protected void installFlow(Intent intent, Flow flow) {
        InstallationListener listener = new InstallationListener(flow.getId());
        flowManager.addListener(listener);

        FlowBatchHandle handle = flowManager.addFlow(flow);
        if (handle == null) {
            throw new IntentInstallationException("intent installation failed: " + intent);
        }

        try {
            listener.await();
            if (listener.getFinalState() == FAILED) {
                throw new IntentInstallationException("intent installation failed: " + intent);
            }
        } catch (InterruptedException e) {
            throw new IntentInstallationException("intent installation failed: " + intent, e);
        } finally {
            flowManager.removeListener(listener);
        }
    }

    protected void removeFlow(Intent intent, Flow flow) {
        RemovalListener listener = new RemovalListener(flow.getId());
        flowManager.addListener(listener);

        FlowBatchHandle handle = flowManager.removeFlow(flow.getId());
        if (handle == null) {
            throw new IntentRemovalException("intent removal failed: " + intent);
        }


        try {
            listener.await();
            if (listener.getFinalState() == FAILED) {
                throw new IntentInstallationException("intent removal failed: " + intent);
            }
        } catch (InterruptedException e) {
            throw new IntentInstallationException("intent removal failed: " + intent, e);
        } finally {
            flowManager.removeListener(listener);
        }
    }

    protected abstract static class SyncListener implements FlowManagerListener {
        protected final FlowId target;
        protected final CountDownLatch latch = new CountDownLatch(1);
        protected FlowState finalState;

        protected SyncListener(FlowId target) {
            this.target = checkNotNull(target);
        }

        protected Optional<FlowStateChange> findTargetFlow(FlowStatesChangedEvent event) {
            return Iterables.tryFind(event.getStateChanges(), new Predicate<FlowStateChange>() {
                @Override
                public boolean apply(FlowStateChange stateChange) {
                    return stateChange.getFlowId().equals(target);
                }
            });
        }

        public FlowState getFinalState() {
            return finalState;
        }

        public void await() throws InterruptedException {
            latch.await();
        }
    }

    protected static class InstallationListener extends SyncListener {
        public InstallationListener(FlowId target) {
            super(target);
        }

        @Override
        public void flowStatesChanged(FlowStatesChangedEvent event) {
            Optional<FlowStateChange> optional = findTargetFlow(event);

            if (!optional.isPresent()) {
                return;
            }

            FlowStateChange stateChange = optional.get();
            switch (stateChange.getCurrentState()) {
                case INSTALLED:
                    latch.countDown();
                    finalState = INSTALLED;
                    break;
                case FAILED:
                    latch.countDown();
                    finalState = FAILED;
                    break;
                default:
                    break;
            }
        }

        @Override
        public void flowBatchStateChanged(FlowBatchStateChangedEvent event) {
            // nop
        }
    }

    protected static class RemovalListener extends SyncListener {
        public RemovalListener(FlowId target) {
            super(target);
        }

        @Override
        public void flowStatesChanged(FlowStatesChangedEvent event) {
            Optional<FlowStateChange> optional = findTargetFlow(event);

            if (!optional.isPresent()) {
                return;
            }

            FlowStateChange stateChange = optional.get();
            switch (stateChange.getCurrentState()) {
                case WITHDRAWN:
                    latch.countDown();
                    finalState = WITHDRAWN;
                    break;
                case FAILED:
                    latch.countDown();
                    finalState = FAILED;
                    break;
                default:
                    break;
            }
        }

        @Override
        public void flowBatchStateChanged(FlowBatchStateChangedEvent event) {
            // nop
        }
    }
}
