// 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.persistence.syncbase;

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

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Nullable;

import io.v.todos.model.ListMetadata;
import io.v.todos.model.ListSpec;
import io.v.todos.model.TaskSpec;
import io.v.todos.persistence.ListEventListener;
import io.v.v23.InputChannel;
import io.v.v23.InputChannelCallback;
import io.v.v23.InputChannels;
import io.v.v23.context.VContext;
import io.v.v23.services.syncbase.Id;
import io.v.v23.syncbase.ChangeType;
import io.v.v23.syncbase.Collection;
import io.v.v23.syncbase.Database;
import io.v.v23.syncbase.WatchChange;
import io.v.v23.syncbase.util.Util;
import io.v.v23.verror.NoExistException;

/**
 * This class aggregates Todo-list watch data from Syncbase into {@link ListMetadata}.
 */
public class MainListTracker {
    private static final String TAG = MainListTracker.class.getSimpleName();

    private final ListEventListener<ListMetadata> mListener;
    private ListSpec mListSpec;

    private final Map<String, Boolean> mIsTaskCompleted = new HashMap<>();
    private int mNumCompletedTasks;
    private boolean mListExistsLocally;

    public final Collection collection;
    public final ListenableFuture<Void> watchFuture;

    public MainListTracker(VContext vContext, Database database, final Id listId,
                           ListEventListener<ListMetadata> listener) {
        collection = database.getCollection(listId);
        mListener = listener;
        InputChannel<WatchChange> watch = database.watch(vContext,
                ImmutableList.of(Util.rowPrefixPattern(collection.id(), "")));
        watchFuture = InputChannels.withCallback(watch, new InputChannelCallback<WatchChange>() {
            @Override
            public ListenableFuture<Void> onNext(WatchChange change) {
                processWatchChange(change);
                return null;
            }
        });

        // If the watch fails with NoExistException, the collection has been deleted.
        Futures.addCallback(watchFuture, new FutureCallback<Void>() {
            @Override
            public void onSuccess(@Nullable Void result) {
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                if (t instanceof NoExistException && mListExistsLocally) {
                    Log.d(TAG, getNameFromId() + " destroyed");
                    mListener.onItemDelete(getNameFromId());
                }
            }
        });
    }

    private String getNameFromId() {
        return SyncbasePersistence.convertIdToString(collection.id());
    }

    public ListMetadata getListMetadata() {
        return new ListMetadata(getNameFromId(), mListSpec, mNumCompletedTasks,
                mIsTaskCompleted.size());
    }

    private void processWatchChange(WatchChange change) {
        String rowName = change.getRowName();

        if (rowName.equals(SyncbaseTodoList.LIST_METADATA_ROW_NAME)) {
            mListSpec = SyncbasePersistence.castFromSyncbase(change.getValue(), ListSpec.class);
        } else if (change.getChangeType() == ChangeType.DELETE_CHANGE) {
            if (mIsTaskCompleted.remove(rowName)) {
                mNumCompletedTasks--;
            }
        } else {
            boolean isDone = SyncbasePersistence.castFromSyncbase(change.getValue(), TaskSpec.class)
                    .getDone();
            Boolean rawWasDone = mIsTaskCompleted.put(rowName, isDone);
            boolean wasDone = rawWasDone != null && rawWasDone;
            if (!wasDone && isDone) {
                mNumCompletedTasks++;
            } else if (wasDone && !isDone) {
                mNumCompletedTasks--;
            }
        }

        // Don't fire events until we've processed the entire batch of watch events.
        if (!change.isContinued()) {
            ListMetadata listMetadata = getListMetadata();
            Log.d(TAG, listMetadata.toString());

            if (mListExistsLocally) {
                mListener.onItemUpdate(listMetadata);
            } else {
                mListExistsLocally = true;
                mListener.onItemAdd(listMetadata);
            }
        }
    }
}
