package fr.insa.clavardator.client.server.presence;

import fr.insa.clavardator.client.server.proxy.Proxy;
import fr.insa.clavardator.lib.users.UserInformation;
import fr.insa.clavardator.lib.util.ErrorCallback;
import fr.insa.clavardator.lib.util.ParametrizedCallback;
import fr.insa.clavardator.lib.util.SimpleCallback;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;

/**
 * Interface exposing public methods necessary for any presence server.
 *
 * @implNote Implement this interface when creating your own presence server class,
 * then update the {@link PresenceFactory factory}
 * to add your new implementation.
 */
public interface Presence {

	/**
	 * Subscribes to this presence server notifications and publish current status.
	 * A list of Ids representing the current active users is returned.
	 *
	 * @param callback Called when subscription completes
	 */
	void subscribe(UserInformation userInformation, ParametrizedCallback<ArrayList<UserInformation>> callback, @Nullable ErrorCallback errorCallback);

	/**
	 * Stops subscription to the presence server by closing TCP connections.
	 * This will stop notifications.
	 *
	 * @implNote Call this before exiting the app.
	 * If not, the presence server will wait for a tcp timeout before marking this user as disconnected.
	 */
	void unsubscribe(SimpleCallback callback, @Nullable ErrorCallback errorCallback);

	/**
	 * Notifies the presence server of any changes to the current user
	 *
	 * @param newInformation The new information to send
	 * @param callback       Called when notify completes
	 */
	void notify(UserInformation newInformation, @Nullable SimpleCallback callback, @Nullable ErrorCallback errorCallback);

	/**
	 * Gets the proxy.
	 * This can be used to initialize a
	 * {@link fr.insa.clavardator.client.users.PeerUser Peeruser}
	 * and send messages like on a local network.
	 *
	 * @return The proxy
	 */
	Proxy getProxy();
}
