package org.mercury_im.messenger.core.usecase;

import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.PresenceEventListener;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterListener;
import org.jivesoftware.smack.roster.RosterLoadedListener;
import org.jivesoftware.smack.roster.SubscribeListener;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.mercury_im.messenger.core.connection.MercuryConnection;
import org.mercury_im.messenger.core.store.roster.MercuryRosterStore;
import org.mercury_im.messenger.core.store.roster.MercuryRosterStoreFactory;

import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;

public class RosterStoreBinder {

    private final MercuryRosterStoreFactory rosterStoreFactory;

    private final Logger LOGGER = Logger.getLogger(RosterStoreBinder.class.getName());

    @Inject
    public RosterStoreBinder(MercuryRosterStoreFactory rosterStoreFactory) {

        this.rosterStoreFactory = rosterStoreFactory;
    }

    public void setRosterStoreOn(MercuryConnection connection) {
        MercuryRosterStore store = rosterStoreFactory.createRosterStore(connection.getAccountId());
        Roster roster = Roster.getInstanceFor(connection.getConnection());
        roster.setRosterStore(store);
        roster.addSubscribeListener(new SubscribeListener() {
            @Override
            public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) {
                RosterEntry entry = roster.getEntry(from.asBareJid());
                if (entry != null) {
                    return SubscribeAnswer.ApproveAndAlsoRequestIfRequired;
                }
                LOGGER.log(Level.INFO, "processSubscribe " + from);
                return null;
            }
        });
        roster.addPresenceEventListener(new PresenceEventListener() {
            @Override
            public void presenceAvailable(FullJid address, Presence availablePresence) {
                LOGGER.log(Level.INFO, "presenceAvailable " + address.toString());
            }

            @Override
            public void presenceUnavailable(FullJid address, Presence presence) {
                LOGGER.log(Level.INFO, "presenceUnavailable " + address);
            }

            @Override
            public void presenceError(Jid address, Presence errorPresence) {
                LOGGER.log(Level.INFO, "presenceError " + address);
            }

            @Override
            public void presenceSubscribed(BareJid address, Presence subscribedPresence) {
                LOGGER.log(Level.INFO, "presenceSubscribed " + address);
            }

            @Override
            public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
                LOGGER.log(Level.INFO, "presenceUnsubscribed " + address);
            }
        });
        roster.addRosterListener(new RosterListener() {
            @Override
            public void entriesAdded(Collection<Jid> addresses) {
                LOGGER.log(Level.INFO, "entriesAdded " + Arrays.toString(addresses.toArray()));
            }

            @Override
            public void entriesUpdated(Collection<Jid> addresses) {
                LOGGER.log(Level.INFO, "entriesUpdated " + Arrays.toString(addresses.toArray()));
            }

            @Override
            public void entriesDeleted(Collection<Jid> addresses) {
                LOGGER.log(Level.INFO, "entriesDeleted " + Arrays.toString(addresses.toArray()));
            }

            @Override
            public void presenceChanged(Presence presence) {
                LOGGER.log(Level.INFO, "presenceChanged " + presence.toString());
            }
        });
        roster.addRosterLoadedListener(new RosterLoadedListener() {
            @Override
            public void onRosterLoaded(Roster roster) {
                LOGGER.log(Level.INFO, "onRosterLoaded");
            }

            @Override
            public void onRosterLoadingFailed(Exception exception) {
                LOGGER.log(Level.INFO, "onRosterLoadingFailed");
            }
        });
    }
}
