package org.eclipse.osbp.vaaclipse.addons.app.session;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.osbp.runtime.common.session.AbstractSession;
import org.eclipse.osbp.runtime.common.session.ISession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.ui.UI;

/**
 * This session is registered as an OSGi service any time a new UI-Instance is
 * created.
 */
public class VaaclipseSession extends AbstractSession {

	/**
	 * OSGi service properties.
	 */
	public static String PROP_VAADIN_UI_ID = "vaadinUIId";
	public static String PROP_E4_APP_ID = "e4SessionId";
	public static String PROP_USER_NAME = "userName";
	public static String PROP_LOCALE = "locale";

	private static Logger LOGGER = LoggerFactory.getLogger(VaaclipseSession.class);

	final UI ui;
	final IEclipseContext eclipseContext;

	final List<ISession> slaves = new ArrayList<ISession>();
	private ISession masterSession;
	private final String fragment;

	public VaaclipseSession(UI ui, IEclipseContext eclipseContext, String fragment) {
		super();
		this.ui = ui;
		this.eclipseContext = eclipseContext;
		this.fragment = fragment;
		setType(Type.MASTER);
	}

	@Override
	public <T> T get(Class<T> key) {
		return eclipseContext.get(key);
	}

	@Override
	public Object get(String key) {
		return eclipseContext.get(key);
	}

	@Override
	protected <T> CompletableFuture<T> doAsync(final Function<ISession, T> function, ExecutorService executor) {
		CompletableFuture<T> promise = new CompletableFuture<>();
		runVaadinAsync(function, promise);
		return promise;
	}

	protected <T> void runVaadinAsync(final Function<ISession, T> function, CompletableFuture<T> promise) {
		ui.access(() -> {
			try {
				T value = function.apply(this);
				// notify the promise
				promise.complete(value);
			} catch (Exception e) {
				promise.completeExceptionally(e);
			}
		});
	}

	@Override
	public void set(String key, Object object) {
		eclipseContext.set(key, object);
	}

	@Override
	public List<ISession> getSlaves() {
		return Collections.unmodifiableList(slaves);
	}

	@Override
	public List<ISession> getSlaves(Predicate<ISession> filter) {
		return slaves.stream().filter(filter).collect(Collectors.toList());
	}
	
	@Override
	public void addSlave(ISession slave) {
		if (isSlaveSession()) {
			throw new IllegalStateException("Not allowed for slaves");
		}
		slaves.add(slave);
	}

	@Override
	public void removeSlave(ISession slave) {
		if (isSlaveSession()) {
			throw new IllegalStateException("Not allowed for slaves");
		}
		slaves.remove(slave);
	}

	@Override
	public boolean isMasterSession() {
		return getType() == Type.MASTER;
	}

	@Override
	public boolean isSlaveSession() {
		return getType() == Type.SLAVE;
	}

	@Override
	public ISession getMaster() {
		return masterSession;
	}

	@Override
	public String getHost() {
		try {
			InetAddress netAddress = InetAddress
					.getByName(eclipseContext.get(UI.class).getPage().getWebBrowser().getAddress());
			return netAddress.getHostName();
		} catch (UnknownHostException e) {
			LOGGER.error("{}", e);
			throw new IllegalArgumentException(e);
		}
	}

	@Override
	public String getFragment() {
		return fragment;
	}

}
