/*
 *                                                                            
 *  Copyright (c) 2011 - 2017 - Loetz GmbH & Co KG, 69115 Heidelberg, Germany 
 *                                                                            
 *  All rights reserved. This program and the accompanying materials           
 *  are made available under the terms of the Eclipse Public License 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/
 *
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG                              
 * 
 */
package org.eclipse.osbp.runtime.common.session;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * Is responsible to keep track of all {@link ISession}s in this JVM
 * instance.<br>
 * Sessions are added and removed automatically by the manager.
 */
public interface ISessionManager {

	/**
	 * Returns an unmodifiable list of sessions.
	 * 
	 * @param filter
	 *            an optional filter which is used to filter the sessions before
	 *            they are added to the result list.
	 * @return
	 */
	List<ISession> getSessions(Predicate<ISession> filter);

	/**
	 * Returns an unmodifiable list of sessions. This method MUST NOT block.
	 * 
	 * @param filter
	 *            an optional filter which is used to filter the sessions before
	 *            they are added to the result list.
	 * @return
	 */
	CompletableFuture<List<ISession>> getSessionsAsync(Predicate<ISession> filter);

	/**
	 * Syncs all {@link ISession} with the given function in an async way. This
	 * method MUST NOT block.
	 * 
	 * @param function
	 *            The function to transform the session to a return value.
	 * @return {@link CompletableFuture} which is completed with a list of
	 *         {@link FutureResult}
	 */
	<T> CompletableFuture<List<FutureResult<T>>> asyncAll(Function<ISession, T> function);

	/**
	 * Syncs the {@link ISession}s matching the filter with the given function
	 * in an async way. This method MUST NOT block.
	 * 
	 * @param function
	 *            The function to transform the session to a return value.
	 * @return {@link CompletableFuture} which is completed with a list of
	 *         {@link FutureResult}
	 * @param filter
	 *            an optional filter which is used to filter the sessions before
	 *            they are added to the result list.
	 * @return
	 */
	<T> CompletableFuture<List<FutureResult<T>>> asyncAll(Function<ISession, T> function, Predicate<ISession> filter);

	/**
	 * Syncs all {@link ISession} with the given function in an async way. This
	 * method MUST NOT block.
	 * 
	 * @param function
	 *            The function to transform the session to a return value.
	 * @param callback
	 *            The callback is attached to every future in the resulting list
	 * @return A list of {@link CompletableFuture}s. One
	 *         {@link CompletableFuture} for each async request to
	 *         {@link ISession#async(Function, SessionCallback)}
	 *         {@link FutureResult}
	 */
	<T> List<CompletableFuture<FutureResult<T>>> asyncEach(Function<ISession, T> function, SessionCallback<T> callback);

	/**
	 * Syncs the {@link ISession}s matching the filter with the given function
	 * in an async way. This method MUST NOT block.
	 * 
	 * @param function
	 *            The function to transform the session to a return value.
	 * @param callback
	 *            The callback is attached to every future in the resulting list
	 * @param filter
	 *            an optional filter which is used to filter the sessions before
	 *            they are added to the result list.
	 * @return A list of {@link CompletableFuture}s. One
	 *         {@link CompletableFuture} for each async request to
	 *         {@link ISession#async(Function, SessionCallback)}
	 *         {@link FutureResult}
	 */
	<T> List<CompletableFuture<FutureResult<T>>> asyncEach(Function<ISession, T> function, SessionCallback<T> callback,
			Predicate<ISession> filter);

	/**
	 * Gets the session-wide transaction handler.
	 *
	 * @param ui the ui
	 * @return the transaction handler
	 */
	ITransactionHandler getTransactionHandler(Object ui);
	
	/**
	 * Sets the session-wide transaction handler.
	 *
	 * @param ui the ui
	 * @param txn the txn
	 * @return true, if successful
	 */
	boolean setTransactionHandler(Object ui, ITransactionHandler txn);
	
	/**
	 * Dispose the session-wide transaction handler.
	 *
	 * @param ui the ui
	 * @return true, if successful
	 */
	boolean disposeTransactionHandler(Object ui);
	
	class FutureResult<T> {
		public final ISession session;
		public final T value;
		public final Throwable error;

		public final boolean isError;

		public FutureResult(ISession session, T value, Throwable error) {
			super();
			this.session = session;
			this.value = value;
			this.error = error;

			isError = error != null;
		}

	}
}
