package net.onrc.onos.core.newintent;

import com.google.common.collect.ImmutableMap;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import net.onrc.onos.api.newintent.InstallableIntent;
import net.onrc.onos.api.newintent.Intent;
import net.onrc.onos.api.newintent.IntentCompiler;
import net.onrc.onos.api.newintent.IntentEvent;
import net.onrc.onos.api.newintent.IntentEventListener;
import net.onrc.onos.api.newintent.IntentException;
import net.onrc.onos.api.newintent.IntentId;
import net.onrc.onos.api.newintent.IntentInstaller;
import net.onrc.onos.api.newintent.IntentManager;
import net.onrc.onos.api.newintent.IntentOperations;
import net.onrc.onos.api.newintent.IntentState;
import net.onrc.onos.core.datagrid.ISharedCollectionsService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.google.common.base.Preconditions.checkNotNull;
import static net.onrc.onos.api.newintent.IntentState.COMPILED;
import static net.onrc.onos.api.newintent.IntentState.FAILED;
import static net.onrc.onos.api.newintent.IntentState.INSTALLED;
import static net.onrc.onos.api.newintent.IntentState.SUBMITTED;
import static net.onrc.onos.api.newintent.IntentState.WITHDRAWING;
import static net.onrc.onos.api.newintent.IntentState.WITHDRAWN;

/**
 * An implementation of Intent Manager.
 */
public class IntentManagerRuntime implements IntentManager {
    // Collections for intent, installable intent, and intent state are globally shared
    private final IntentMap<IntentEvent> intentEvents;
    private final IntentMap<IntentCompilationResult> installableIntents;

    // Collections for compiler, installer, and listener are ONOS instance local
    private final ConcurrentMap<Class<? extends Intent>,
            IntentCompiler<? extends Intent>> compilers = new ConcurrentHashMap<>();
    private final ConcurrentMap<Class<? extends InstallableIntent>,
            IntentInstaller<? extends InstallableIntent>> installers = new ConcurrentHashMap<>();
    private final CopyOnWriteArrayList<IntentEventListener> listeners = new CopyOnWriteArrayList<>();

    /**
     * Constructs a Intent Manager runtime with the specified shared collections service.
     *
     * @param collectionsService shared collections service
     */
    public IntentManagerRuntime(ISharedCollectionsService collectionsService) {
        checkNotNull(collectionsService);

        this.intentEvents = new IntentMap<>("intentState", IntentEvent.class, collectionsService);
        this.installableIntents =
                new IntentMap<>("installableIntents", IntentCompilationResult.class, collectionsService);

        this.intentEvents.addListener(new InternalEntryListener(new InternalIntentEventListener()));
    }

    @Override
    public void submit(Intent intent) {
        registerSubclassCompilerIfNeeded(intent);
        setState(intent, SUBMITTED);
    }

    @Override
    public void withdraw(Intent intent) {
        setState(intent, WITHDRAWING);
    }

    // FIXME: implement this method
    @Override
    public void execute(IntentOperations operations) {
        throw new UnsupportedOperationException("execute() is not implemented yet");
    }

    @Override
    public Set<Intent> getIntents() {
        Collection<IntentEvent> events = intentEvents.values();
        Set<Intent> intents = new HashSet<>(events.size());
        for (IntentEvent event: events) {
            intents.add(event.getIntent());
        }
        return intents;
    }

    @Override
    public Intent getIntent(IntentId id) {
        IntentEvent event = intentEvents.get(id);
        if (event == null) {
            return null;
        }
        return event.getIntent();
    }

    @Override
    public IntentState getIntentState(IntentId id) {
        IntentEvent event = intentEvents.get(id);
        if (event == null) {
            return null;
        }
        return event.getState();
    }

    @Override
    public void addListener(IntentEventListener listener) {
        listeners.add(listener);
    }

    @Override
    public void removeListener(IntentEventListener listener) {
        listeners.remove(listener);
    }

    @Override
    public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
        compilers.put(cls, compiler);
    }

    @Override
    public <T extends Intent> void unregisterCompiler(Class<T> cls) {
        compilers.remove(cls);
    }

    @Override
    public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
        return ImmutableMap.copyOf(compilers);
    }

    @Override
    public <T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
        installers.put(cls, installer);
    }

    @Override
    public <T extends InstallableIntent> void unregisterInstaller(Class<T> cls) {
        installers.remove(cls);
    }

    @Override
    public Map<Class<? extends InstallableIntent>, IntentInstaller<? extends InstallableIntent>> getInstallers() {
        return ImmutableMap.copyOf(installers);
    }

    /**
     * Sets the state of the specified intent to the new state.
     *
     * @param intent intent whose state is to be changed
     * @param newState new state
     */
    private void setState(Intent intent, IntentState newState) {
        IntentState oldState = getIntentState(intent.getId());
        IntentEvent event = new IntentEvent(intent, newState, oldState, System.currentTimeMillis());
        intentEvents.put(intent.getId(), event);
    }

    /**
     * Invokes all of registered intent event listener.
     *
     * @param event event supplied to a listener as an argument
     */
    private void invokeListeners(IntentEvent event) {
        for (IntentEventListener listener: listeners) {
            listener.event(event);
        }
    }

    /**
     * Returns the corresponding intent compiler to the specified intent.
     *
     * @param intent intent
     * @param <T> the type of intent
     * @return intent compiler corresponding to the specified intent
     */
    private <T extends Intent> IntentCompiler<T> getCompiler(T intent) {
        @SuppressWarnings("unchecked")
        IntentCompiler<T> compiler = (IntentCompiler<T>) compilers.get(intent.getClass());
        if (compiler == null) {
            throw new IntentException("no compiler for class " + intent.getClass());
        }
        return compiler;
    }

    /**
     * Returns the corresponding intent installer to the specified installable intent.
     * @param intent intent
     * @param <T> the type of installable intent
     * @return intent installer corresponding to the specified installable intent
     */
    private <T extends InstallableIntent> IntentInstaller<T> getInstaller(T intent) {
        @SuppressWarnings("unchecked")
        IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
        if (installer == null) {
            throw new IntentException("no installer for class " + intent.getClass());
        }
        return installer;
    }

    /**
     * Compiles an intent.
     *
     * @param intent intent
     */
    private void compileIntent(Intent intent) {
        // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented
        // TODO: implement compilation traversing tree structure
        List<InstallableIntent> installable = new ArrayList<>();
        for (Intent compiled : getCompiler(intent).compile(intent)) {
            installable.add((InstallableIntent) compiled);
        }
        installableIntents.put(intent.getId(), new IntentCompilationResult(installable));
        setState(intent, COMPILED);
    }

    /**
     * Installs an intent.
     *
     * @param intent intent
     */
    private void installIntent(Intent intent) {
        IntentCompilationResult compiled = installableIntents.get(intent.getId());
        for (InstallableIntent installable: compiled.getResult()) {
            registerSubclassInstallerIfNeeded(installable);
            getInstaller(installable).install(installable);
        }

        setState(intent, INSTALLED);
    }

    /**
     * Uninstalls an intent.
     *
     * @param intent intent
     */
    private void uninstallIntent(Intent intent) {
        IntentCompilationResult compiled = installableIntents.get(intent.getId());
        for (InstallableIntent installable: compiled.getResult()) {
            getInstaller(installable).remove(installable);
        }

        installableIntents.remove(intent.getId());
        setState(intent, WITHDRAWN);
    }

    /**
     * Registers an intent compiler of the specified intent if an intent compiler
     * for the intent is not registered. This method traverses the class hierarchy of
     * the intent. Once an intent compiler for a parent type is found, this method
     * registers the found intent compiler.
     *
     * @param intent intent
     */
    @SuppressWarnings("unchecked")
    private void registerSubclassCompilerIfNeeded(Intent intent) {
        if (!compilers.containsKey(intent.getClass())) {
            Class<?> cls = intent.getClass();
            while (cls != Object.class) {
                // As long as we're within the Intent class descendants
                if (Intent.class.isAssignableFrom(cls)) {
                    IntentCompiler<?> compiler = compilers.get(cls);
                    if (compiler != null) {
                        compilers.put(intent.getClass(), compiler);
                        return;
                    }
                }
                cls = cls.getSuperclass();
            }
        }
    }

    /**
     * Registers an intent installer of the specified intent if an intent installer
     * for the intent is not registered. This method traverses the class hierarchy of
     * the intent. Once an intent installer for a parent type is found, this method
     * registers the found intent installer.
     *
     * @param intent intent
     */
    @SuppressWarnings("unchecked")
    private void registerSubclassInstallerIfNeeded(InstallableIntent intent) {
        if (!installers.containsKey(intent.getClass())) {
            Class<?> cls = intent.getClass();
            while (cls != Object.class) {
                // As long as we're within the InstallableIntent class descendants
                if (InstallableIntent.class.isAssignableFrom(cls)) {
                    IntentInstaller<?> installer = installers.get(cls);
                    if (installer != null) {
                        installers.put(intent.getClass(), installer);
                        return;
                    }
                }
                cls = cls.getSuperclass();
            }
        }
    }

    /**
     * Destroys underlying {@link IntentMap IntentMaps}.
     * This method is only for testing purpose.
     */
    void destroy() {
        intentEvents.destroy();
        installableIntents.destroy();
    }

    /**
     * An entry listener used internally.
     *
     * This listener is a kind of bridge of listener mechanism
     * between {@link IntentMap} and {@link IntentEventListener}.
     */
    private static class InternalEntryListener implements EntryListener<IntentId, IntentEvent> {
        private final IntentEventListener listener;

        public InternalEntryListener(IntentEventListener listener) {
            this.listener = listener;
        }

        @Override
        public void entryAdded(EntryEvent<IntentId, IntentEvent> event) {
            listener.event(event.getValue());
        }

        @Override
        public void entryRemoved(EntryEvent<IntentId, IntentEvent> event) {
            listener.event(event.getValue());
        }

        @Override
        public void entryUpdated(EntryEvent<IntentId, IntentEvent> event) {
            listener.event(event.getValue());
        }

        @Override
        public void entryEvicted(EntryEvent<IntentId, IntentEvent> event) {
            // no-op
        }
    }

    /**
     * An intent event listener used internally.
     *
     * event() method handles state transition of submitted intents.
     */
    private class InternalIntentEventListener implements IntentEventListener {
        @Override
        public void event(IntentEvent event) {
            invokeListeners(event);
            Intent intent = event.getIntent();

            try {
                switch (event.getState()) {
                    case SUBMITTED:
                        compileIntent(intent);
                        break;
                    case COMPILED:
                        installIntent(intent);
                        break;
                    case INSTALLED:
                        break;
                    case WITHDRAWING:
                        uninstallIntent(intent);
                        break;
                    case WITHDRAWN:
                        break;
                    case FAILED:
                        break;
                    default:
                        throw new IllegalStateException(
                                "the state of IntentEvent is illegal: " + event.getState());
                }
            } catch (IntentException e) {
                setState(intent, FAILED);
            }
        }
    }
}
