package org.onlab.onos.net.intent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Fake implementation of the intent service to assist in developing tests of
 * the interface contract.
 */
public class FakeIntentManager implements TestableIntentService {

    private final Map<IntentId, Intent> intents = new HashMap<>();
    private final Map<IntentId, IntentState> intentStates = new HashMap<>();
    private final Map<IntentId, List<InstallableIntent>> installables = new HashMap<>();
    private final Set<IntentListener> listeners = new HashSet<>();

    private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
    private final Map<Class<? extends InstallableIntent>, IntentInstaller<? extends InstallableIntent>> installers
        = new HashMap<>();

    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final List<IntentException> exceptions = new ArrayList<>();

    @Override
    public List<IntentException> getExceptions() {
        return exceptions;
    }

    // Provides an out-of-thread simulation of intent submit life-cycle
    private void executeSubmit(final Intent intent) {
        registerSubclassCompilerIfNeeded(intent);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    executeCompilingPhase(intent);
                } catch (IntentException e) {
                    exceptions.add(e);
                }
            }
        });
    }

    // Provides an out-of-thread simulation of intent withdraw life-cycle
    private void executeWithdraw(final Intent intent) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    List<InstallableIntent> installable = getInstallable(intent.id());
                    executeWithdrawingPhase(intent, installable);
                } catch (IntentException e) {
                    exceptions.add(e);
                }

            }
        });
    }

    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;
    }

    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;
    }

    private <T extends Intent> void executeCompilingPhase(T intent) {
        setState(intent, IntentState.COMPILING);
        try {
            // For the fake, we compile using a single level pass
            List<InstallableIntent> installable = new ArrayList<>();
            for (Intent compiled : getCompiler(intent).compile(intent)) {
                installable.add((InstallableIntent) compiled);
            }
            executeInstallingPhase(intent, installable);

        } catch (IntentException e) {
            setState(intent, IntentState.FAILED);
            dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
        }
    }

    private void executeInstallingPhase(Intent intent,
                                        List<InstallableIntent> installable) {
        setState(intent, IntentState.INSTALLING);
        try {
            for (InstallableIntent ii : installable) {
                registerSubclassInstallerIfNeeded(ii);
                getInstaller(ii).install(ii);
            }
            setState(intent, IntentState.INSTALLED);
            putInstallable(intent.id(), installable);
            dispatch(new IntentEvent(IntentEvent.Type.INSTALLED, intent));

        } catch (IntentException e) {
            setState(intent, IntentState.FAILED);
            dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
        }
    }

    private void executeWithdrawingPhase(Intent intent,
                                         List<InstallableIntent> installable) {
        setState(intent, IntentState.WITHDRAWING);
        try {
            for (InstallableIntent ii : installable) {
                getInstaller(ii).uninstall(ii);
            }
            removeInstallable(intent.id());
            setState(intent, IntentState.WITHDRAWN);
            dispatch(new IntentEvent(IntentEvent.Type.WITHDRAWN, intent));
        } catch (IntentException e) {
            // FIXME: Rework this to always go from WITHDRAWING to WITHDRAWN!
            setState(intent, IntentState.FAILED);
            dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
        }
    }

    // Sets the internal state for the given intent and dispatches an event
    private void setState(Intent intent, IntentState state) {
        intentStates.put(intent.id(), state);
    }

    private void putInstallable(IntentId id, List<InstallableIntent> installable) {
        installables.put(id, installable);
    }

    private void removeInstallable(IntentId id) {
        installables.remove(id);
    }

    private List<InstallableIntent> getInstallable(IntentId id) {
        List<InstallableIntent> installable = installables.get(id);
        if (installable != null) {
            return installable;
        } else {
            return Collections.emptyList();
        }
    }

    @Override
    public void submit(Intent intent) {
        intents.put(intent.id(), intent);
        setState(intent, IntentState.SUBMITTED);
        dispatch(new IntentEvent(IntentEvent.Type.SUBMITTED, intent));
        executeSubmit(intent);
    }

    @Override
    public void withdraw(Intent intent) {
        intents.remove(intent.id());
        executeWithdraw(intent);
    }

    @Override
    public void execute(IntentOperations operations) {
        // TODO: implement later
    }

    @Override
    public Set<Intent> getIntents() {
        return Collections.unmodifiableSet(new HashSet<>(intents.values()));
    }

    @Override
    public long getIntentCount() {
        return intents.size();
    }

    @Override
    public Intent getIntent(IntentId id) {
        return intents.get(id);
    }

    @Override
    public IntentState getIntentState(IntentId id) {
        return intentStates.get(id);
    }

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

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

    private void dispatch(IntentEvent event) {
        for (IntentListener listener : listeners) {
            listener.event(event);
        }
    }

    @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 Collections.unmodifiableMap(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 Collections.unmodifiableMap(installers);
    }

    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();
            }
        }
    }

    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();
            }
        }
    }

}
