001package org.intellimate.izou.sdk.frameworks.presence.consumer;
002
003import org.intellimate.izou.events.EventListenerModel;
004import org.intellimate.izou.events.EventModel;
005import org.intellimate.izou.sdk.frameworks.presence.events.LeavingEvent;
006import org.intellimate.izou.sdk.frameworks.presence.events.PresenceEvent;
007import org.intellimate.izou.sdk.util.ContextProvider;
008
009import java.util.Collections;
010import java.util.concurrent.CompletableFuture;
011import java.util.function.Consumer;
012
013/**
014 * provides various methods to get notified when the presence event got fired.
015 * @author LeanderK
016 * @version 1.0
017 */
018@SuppressWarnings("unused")
019public interface PresenceEventUser extends ContextProvider {
020    /**
021     * registers the the passed Consumer as a callback which will be called when an presence event was fired.
022     * <p>
023     * You must unregister the returned EventListenerModel when you are not using the Callback anymore!
024     * </p>
025     * @param callback the callback to use
026     * @param strict whether the callback should only be fired when the addon when the user is very likely near izou
027     * @param known whether the callback should only be fired when the person causing the evens is very likely the user
028     * @return the EventListener used to unregister at the Context
029     */
030    @SuppressWarnings("unused")
031    default EventListenerModel registerPresenceCallback(Consumer<EventModel> callback, boolean strict, boolean known) {
032        return registerPresenceCallback(callback, strict, known, false);
033    }
034
035    /**
036     * registers the the passed Consumer as a callback which will be called when an presence event was fired.
037     * <p>
038     * You must unregister the returned EventListenerModel when you are not using the Callback anymore!
039     * </p>
040     * @param callback the callback to use
041     * @param strict whether the callback should only be fired when the addon when the user is very likely near izou
042     * @param known whether the callback should only be fired when the person causing the evens is very likely the user
043     * @param firstEncounter whether the callback should only be fired when its the first encounter after the user left
044     * @return the EventListener used to unregister at the Context
045     */
046    @SuppressWarnings("unused")
047    default EventListenerModel registerPresenceCallback(Consumer<EventModel> callback, boolean strict, boolean known, boolean firstEncounter) {
048        EventListenerModel eventListenerModel = event -> {
049            if (strict && !event.containsDescriptor(PresenceEvent.STRICT_DESCRIPTOR)) {
050                return;
051            }
052            if (known && !event.containsDescriptor(PresenceEvent.KNOWN_DESCRIPTOR)) {
053                return;
054            }
055            if (firstEncounter && !event.containsDescriptor(PresenceEvent.FIRST_ENCOUNTER_DESCRIPTOR)) {
056                return;
057            }
058            callback.accept(event);
059        };
060        getContext().getEvents().registerEventListener(Collections.singletonList(PresenceEvent.ID), eventListenerModel);
061        return eventListenerModel;
062    }
063
064    /**
065     * returns a CompletableFuture, that completes when the next specified presence-event was fired
066     * @param strict whether it is very likely that the user is near
067     * @param known whether it is very likely that the person causing the event is the user
068     * @return an instance of CompletableFuture
069     */
070    @SuppressWarnings("unused")
071    default CompletableFuture<EventModel> nextPresence(boolean strict, boolean known) {
072        return nextPresence(strict, known, false);
073    }
074
075    /**
076     * returns a CompletableFuture, that completes when the next specified presence-event was fired
077     * @param strict whether it is very likely that the user is near
078     * @param known whether it is very likely that the person causing the event is the user
079     * @param firstEncounter whether any other than the first encounter after the user left should be ignored
080     * @return an instance of CompletableFuture
081     */
082    @SuppressWarnings("unused")
083    default CompletableFuture<EventModel> nextPresence(boolean strict, boolean known, boolean firstEncounter) {
084        CompletableFuture<EventModel> completableFuture = new CompletableFuture<>();
085        EventListenerModel eventListenerModel = event -> {
086            if (strict && !event.containsDescriptor(PresenceEvent.STRICT_DESCRIPTOR)) {
087                return;
088            }
089            if (known && !event.containsDescriptor(PresenceEvent.KNOWN_DESCRIPTOR)) {
090                return;
091            }
092            if (firstEncounter && !event.containsDescriptor(PresenceEvent.FIRST_ENCOUNTER_DESCRIPTOR)) {
093                return;
094            }
095            completableFuture.complete(event);
096        };
097        getContext().getEvents().registerEventListener(Collections.singletonList(PresenceEvent.ID), eventListenerModel);
098        return completableFuture.whenComplete((event, throwable) ->
099                getContext().getEvents().unregisterEventListener(eventListenerModel));
100    }
101
102    /**
103     * registers the the passed Consumer as a callback which will be called when an leaving event was fired.
104     * <p>
105     * You must unregister the returned EventListenerModel when you are not using the Callback anymore!
106     * </p>
107     * @param callback the callback to use
108     * @param strict whether the callback should only be fired when the addon when the user was very likely near izou
109     * @return the EventListener used to unregister at the Context
110     */
111    @SuppressWarnings("unused")
112    default EventListenerModel registerLeavingCallback(Consumer<EventModel> callback, boolean strict) {
113        EventListenerModel eventListenerModel = event -> {
114            if (strict && !event.containsDescriptor(LeavingEvent.STRICT_DESCRIPTOR)) {
115                return;
116            }
117            callback.accept(event);
118        };
119        getContext().getEvents().registerEventListener(Collections.singletonList(LeavingEvent.ID), eventListenerModel);
120        return eventListenerModel;
121    }
122
123    /**
124     * returns a CompletableFuture, that completes when the next specified leaving-event was fired
125     * @param strict whether it is very likely that the user was near
126     * @return an instance of CompletableFuture
127     */
128    @SuppressWarnings("unused")
129    default CompletableFuture<EventModel> nextLeaving(boolean strict) {
130        CompletableFuture<EventModel> completableFuture = new CompletableFuture<>();
131        EventListenerModel eventListenerModel = event -> {
132            if (strict && !event.containsDescriptor(LeavingEvent.STRICT_DESCRIPTOR)) {
133                return;
134            }
135            completableFuture.complete(event);
136        };
137        getContext().getEvents().registerEventListener(Collections.singletonList(LeavingEvent.ID), eventListenerModel);
138        return completableFuture.whenComplete((event, throwable) ->
139                getContext().getEvents().unregisterEventListener(eventListenerModel));
140    }
141}