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;
import java.util.concurrent.Future;

/**
 * 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<Intent>> 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 Intent>, IntentInstaller<? extends Intent>> 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<Intent> 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 Intent> 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<Intent> installable = new ArrayList<>();
            for (Intent compiled : getCompiler(intent).compile(intent)) {
                installable.add((Intent) compiled);
            }
            executeInstallingPhase(intent, installable);

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

    private void executeInstallingPhase(Intent intent,
                                        List<Intent> installable) {
        setState(intent, IntentState.INSTALLING);
        try {
            for (Intent 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<Intent> installable) {
        setState(intent, IntentState.WITHDRAWING);
        try {
            for (Intent 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<Intent> installable) {
        installables.put(id, installable);
    }

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

    private List<Intent> getInstallable(IntentId id) {
        List<Intent> 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 replace(IntentId oldIntentId, Intent newIntent) {
        // TODO: implement later
    }

    @Override
    public Future<IntentOperations> execute(IntentOperations operations) {
        // TODO: implement later
        return null;
    }

    @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 List<Intent> getInstallableIntents(IntentId intentId) {
        return installables.get(intentId);
    }

    @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 Intent> void registerInstaller(Class<T> cls,
            IntentInstaller<T> installer) {
        installers.put(cls, installer);
    }

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

    @Override
    public Map<Class<? extends Intent>,
    IntentInstaller<? extends Intent>> 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(Intent intent) {
        if (!installers.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)) {
                    IntentInstaller<?> installer = installers.get(cls);
                    if (installer != null) {
                        installers.put(intent.getClass(), installer);
                        return;
                    }
                }
                cls = cls.getSuperclass();
            }
        }
    }

}
