package io.openems.backend.common.edge;

import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import org.osgi.annotation.versioning.ProviderType;

import com.google.gson.JsonElement;
import com.google.gson.JsonNull;

import io.openems.backend.common.metadata.User;
import io.openems.common.jsonrpc.base.JsonrpcNotification;
import io.openems.common.jsonrpc.base.JsonrpcRequest;
import io.openems.common.jsonrpc.base.JsonrpcResponseSuccess;
import io.openems.common.jsonrpc.request.SubscribeSystemLogRequest;
import io.openems.common.session.Role;
import io.openems.common.types.ChannelAddress;

@ProviderType
public interface EdgeManager {

	/**
	 * Send an authenticated JSON-RPC Request to an Edge via Websocket and expect a
	 * JSON-RPC Response.
	 *
	 * @param edgeId  the Edge-ID
	 * @param user    the authenticated {@link User}
	 * @param role    the role of the user on this edge
	 * @param request the {@link JsonrpcRequest}
	 * @return the JSON-RPC Success Response Future
	 */
	public CompletableFuture<JsonrpcResponseSuccess> send(String edgeId, User user, Role role, JsonrpcRequest request);

	/**
	 * Send a JSON-RPC Notification to an Edge.
	 *
	 * @param edgeId       the Edge-ID
	 * @param notification the JsonrpcNotification
	 * @return true if sending was successful; false otherwise
	 */
	public boolean send(String edgeId, JsonrpcNotification notification);

	/**
	 * Handles a {@link SubscribeSystemLogRequest}.
	 *
	 * @param edgeId      the Edge-ID
	 * @param user        the {@link User}
	 * @param role        the role of the user on this edge
	 * @param websocketId the id of the UI websocket connection
	 * @param request     the {@link SubscribeSystemLogRequest}
	 * @return a reply
	 */
	public CompletableFuture<JsonrpcResponseSuccess> handleSubscribeSystemLogRequest(String edgeId, User user,
			Role role, UUID websocketId, SubscribeSystemLogRequest request);

	/**
	 * Gets the latest values for the given ChannelAddresses.
	 *
	 * @param edgeId           The unique Edge-ID
	 * @param channelAddresses The {@link ChannelAddress}es
	 * @return the values; possibly {@link JsonNull}
	 */
	public SortedMap<ChannelAddress, JsonElement> getChannelValues(String edgeId, Set<ChannelAddress> channelAddresses);

	/**
	 * Gets the {@link EdgeCache} of the WebSocket connection for an Edge-ID. If
	 * more than one connection exists, the EdgeCache of the first one is returned.
	 * Returns null if none is found.
	 *
	 * @param edgeId the Edge-ID
	 * @return the {@link EdgeCache}
	 */
	public EdgeCache getEdgeCacheForEdgeId(String edgeId);

}
