// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package io.v.todos.sharing;

import android.support.annotation.NonNull;
import android.util.Log;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import io.v.android.v23.V;
import io.v.todos.R;
import io.v.todos.persistence.syncbase.SyncbasePersistence;
import io.v.v23.InputChannelCallback;
import io.v.v23.InputChannels;
import io.v.v23.context.VContext;
import io.v.v23.discovery.Advertisement;
import io.v.v23.discovery.Discovery;
import io.v.v23.discovery.Update;
import io.v.v23.security.BlessingPattern;
import io.v.v23.syncbase.ChangeType;
import io.v.v23.syncbase.WatchChange;
import io.v.v23.verror.VException;

public final class Sharing {
    private Sharing() {
    }

    private static final String OWNER_KEY = "owner";
    private static final Object sDiscoveryMutex = new Object();
    private static Discovery sDiscovery;
    private static VContext sScanContext;
    private static VContext sAdvertiseContext;
    private final static Map<String, VContext> sAdContextMap = new HashMap<>();

    public static Discovery getDiscovery() {
        return sDiscovery;
    }

    public static void initDiscovery() throws VException {
        synchronized (sDiscoveryMutex) {
            if (sDiscovery == null) {
                sDiscovery = V.newDiscovery(SyncbasePersistence.getAppVContext());

                // Rely on the neighborhood fragment to initialize presence advertisement.
                NeighborhoodFragment.initSharePresence();

                sScanContext = initScanForInvites();
                sAdvertiseContext = initAdvertiseLists();
            }
        }
    }

    // TODO(alexfandrianto): Nobody calls this, so we never stop sharing.
    public static void stopDiscovery() {
        synchronized (sDiscoveryMutex) {
            sScanContext.cancel();
            sAdvertiseContext.cancel();
            sAdContextMap.clear();
        }
    }

    private static String getRootInterface() {
        return SyncbasePersistence.getAppContext().getPackageName();
    }

    public static String getPresenceInterface() {
        return getRootInterface() + ".presence";
    }

    public static String getInvitationInterface() {
        return getRootInterface() + ".invitation";
    }

    /**
     * Starts a scanner seeking advertisements that invite this user to a todo list. When an invite
     * is found, the app will automatically accept it.
     */
    public static VContext initScanForInvites()
            throws VException {
        VContext vContext = SyncbasePersistence.getAppVContext().withCancel();
        try {
            ListenableFuture<Void> scan = InputChannels.withCallback(
                    Sharing.getDiscovery().scan(vContext,
                            "v.InterfaceName = \"" + Sharing.getInvitationInterface() + "\""),
                    new InputChannelCallback<Update>() {
                        @Override
                        public ListenableFuture<Void> onNext(Update result) {
                            final String listName = Iterables.getOnlyElement(result.getAddresses());
                            if (listName == null) {
                                return null;
                            }
                            Log.d("SHARING", "Noticed advertised list: " + listName + " by: " +
                                    result.getAttribute(OWNER_KEY));

                            // TODO(alexfandrianto): Remove hack.
                            // https://github.com/vanadium/issues/issues/1328
                            if (result.getAttribute(SyncbasePersistence
                                    .getPersonalBlessingsString()) == null) {
                                Log.d("SHARING", "...but the ad was not meant for this user.");
                                return null; // ignore; this isn't meant for us
                            }

                            // Never mind about losses, just handle found advertisements.
                            if (!result.isLost()) {
                                Log.d("SHARING", "...and will accept it.");

                                SyncbasePersistence.acceptSharedTodoList(listName, result
                                        .getAttribute(OWNER_KEY));
                            }
                            return null;
                        }
                    });
            Futures.addCallback(scan, new FutureCallback<Void>() {
                @Override
                public void onSuccess(@Nullable Void result) {
                }

                @Override
                public void onFailure(Throwable t) {
                    handleScanListsError(t);
                }
            });
        } catch (VException e) {
            handleScanListsError(e);
        }
        return vContext;
    }

    private static void handleScanListsError(Throwable t) {
        SyncbasePersistence.getAppErrorReporter().onError(R.string.err_scan_lists, t);
    }

    /**
     * Creates advertisements based on the todo lists this user has created thus far and those that
     * are created in the future. The advertisements will need to be targeted to the users that have
     * been invited to the list.
     *
     * @return
     * @throws VException
     */
    public static VContext initAdvertiseLists()
            throws VException {
        final VContext vContext = SyncbasePersistence.getAppVContext().withCancel();

        // Prepare a watch on top of the userdata collection to determine which todo lists need to
        // be tracked by this application.
        SyncbasePersistence.watchUserCollection(new InputChannelCallback<WatchChange>() {
            @Override
            public ListenableFuture<Void> onNext(WatchChange change) {
                final String listId = change.getRowName();
                final String owner = SyncbasePersistence.castFromSyncbase(change.getValue(),
                        String.class);
                if (!owner.equals(SyncbasePersistence.getPersonalBlessingsString())) {
                    return Futures.immediateFuture((Void) null);
                }

                if (change.getChangeType() == ChangeType.DELETE_CHANGE) {
                    VContext ctx = sAdContextMap.remove(listId);
                    ctx.cancel(); // Stop advertising the list; it's been deleted.
                } else {
                    // We should probably start to advertise this collection and check its spec.
                    SyncbasePersistence.watchSharedTo(listId, new Function<List<BlessingPattern>,
                            Void>() {
                        @Override
                        public Void apply(List<BlessingPattern> patterns) {
                            // Make a copy of the patterns list that excludes the cloud and this
                            // user's blessings.
                            List<BlessingPattern> filteredPatterns = new ArrayList<>();
                            for (BlessingPattern pattern : patterns) {
                                String pStr = pattern.toString();
                                if (pStr.equals(SyncbasePersistence.getPersonalBlessingsString()) ||
                                        pStr.equals(SyncbasePersistence.CLOUD_BLESSING)) {
                                    continue;
                                }
                                filteredPatterns.add(pattern);
                            }

                            // Advertise to the remaining patterns.
                            if (filteredPatterns.size() > 0) {
                                Log.d("SHARING", "Must advertise for " + listId + " to " +
                                        filteredPatterns.toString());
                                advertiseList(vContext, listId, filteredPatterns);
                            }
                            return null;
                        }
                    });
                }
                return null;
            }
        });
        return vContext;
    }

    /**
     * Advertises that this list is available to this set of people. Cancels the old advertisement
     * if one exists. Only called by initAdvertiseLists.
     *
     * @param baseContext The context for all advertisements
     * @param listId      The list to be advertised
     * @param patterns    Blessings that the advertisement should target
     */
    private static void advertiseList(VContext baseContext, String listId, List<BlessingPattern>
            patterns) {
        if (baseContext.isCanceled()) {
            Log.w("SHARING", "Base context was canceled; cannot advertise");
            return;
        }
        // Swap out the ad context...
        VContext oldAdContext = sAdContextMap.remove(listId);
        if (oldAdContext != null) {
            oldAdContext.cancel();
        }
        VContext newAdContext = baseContext.withCancel();
        sAdContextMap.put(listId, newAdContext);


        try {
            Advertisement ad = new Advertisement();
            ad.setInterfaceName(Sharing.getInvitationInterface());
            ad.getAddresses().add(listId);
            ad.getAttributes().put(OWNER_KEY, SyncbasePersistence.getPersonalBlessingsString());

            // TODO(alexfandrianto): Remove hack. https://github.com/vanadium/issues/issues/1328
            for (BlessingPattern pattern : patterns) {
                ad.getAttributes().put(pattern.toString(), "");
            }

            Futures.addCallback(Sharing.getDiscovery().advertise(sAdvertiseContext, ad,
                    // TODO(alexfandrianto): Crypto crash if I use patterns instead of null.
                    // https://github.com/vanadium/issues/issues/1328 and
                    // https://github.com/vanadium/issues/issues/1331
                    null),
                    //patterns),
                    new FutureCallback<Void>() {
                        @Override
                        public void onSuccess(@android.support.annotation.Nullable Void result) {
                        }

                        @Override
                        public void onFailure(@NonNull Throwable t) {
                            handleAdvertiseListError(t);
                        }
                    });
        } catch (VException e) {
            handleAdvertiseListError(e);
        }
    }

    private static void handleAdvertiseListError(Throwable t) {
        SyncbasePersistence.getAppErrorReporter().onError(R.string.err_advertise_list, t);
    }
}
