package org.mercury_im.messenger.core.data.repository;

import org.jxmpp.jid.EntityBareJid;
import org.mercury_im.messenger.core.util.Optional;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.entity.contact.Peer;

import java.util.List;
import java.util.UUID;

import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;

public interface PeerRepository {

    Single<Peer> insertPeer(Peer Peer);

    default Observable<Optional<Peer>> observePeer(Peer peer) {
        return observePeer(peer.getId());
    }

    Observable<Optional<Peer>> observePeer(UUID PeerId);

    Maybe<Peer> getPeer(UUID PeerId);

    default Observable<Optional<Peer>> observePeerByAddress(Account account, EntityBareJid address) {
        return observePeerByAddress(account.getId(), address);
    }

    Observable<Optional<Peer>> observePeerByAddress(UUID accountId, EntityBareJid address);

    default Maybe<Peer> getPeerByAddress(Account account, EntityBareJid address) {
        return getPeerByAddress(account.getId(), address);
    }

    Maybe<Peer> getPeerByAddress(UUID accountId, EntityBareJid address);

    Single<Peer> getOrCreatePeer(Account account, EntityBareJid address);

    Single<Peer> getOrCreatePeer(UUID accountId, EntityBareJid address);

    Observable<List<Peer>> observeAllPeers();

    default Observable<List<Peer>> observeAllContactsOfAccount(Account account) {
        return observeAllContactsOfAccount(account.getId());
    }

    Observable<List<Peer>> observeAllContactsOfAccount(UUID accountId);

    Single<Peer> updatePeer(Peer Peer);

    Single<Peer> upsertPeer(Peer Peer);

    Completable deletePeer(Peer Peer);

    Completable deletePeer(UUID accountId, EntityBareJid address);

    default Completable deleteAllPeers(Account account) {
        return deleteAllPeers(account.getId());
    }

    Completable deleteAllPeers(UUID accountId);

    Observable<List<Peer>> findPeers(String query);

    Observable<List<Peer>> findPeers(UUID accountId, String query);
}
