// Copyright 2015 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.android.apps.syncslides.db;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.google.common.collect.Lists;

import java.util.List;

import io.v.impl.google.naming.NamingUtil;
import io.v.v23.context.CancelableVContext;
import io.v.v23.context.VContext;
import io.v.v23.syncbase.nosql.BatchDatabase;
import io.v.v23.syncbase.nosql.ChangeType;
import io.v.v23.syncbase.nosql.Database;
import io.v.v23.syncbase.nosql.Stream;
import io.v.v23.syncbase.nosql.Table;
import io.v.v23.syncbase.nosql.WatchChange;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;

/**
 * Watches for changes to the CurrentSlide row.
 */
class CurrentSlideWatcher {

    private static final String TAG = "CurrentSlideWatcher";
    private final CancelableVContext mVContext;
    private final Database mDB;
    private final String mDeckId;
    private final String mPresentationId;
    private final List<DB.CurrentSlideListener> mListeners;
    private final Handler mHandler;
    private VCurrentSlide mCurrentSlide;
    private Thread mThread;

    public CurrentSlideWatcher(VContext vContext, Database db, String deckId,
                               String presentationId) {
        mVContext = vContext.withCancel();
        mDB = db;
        mDeckId = deckId;
        mPresentationId = presentationId;
        mListeners = Lists.newArrayList();
        mHandler = new Handler(Looper.getMainLooper());
        mCurrentSlide = new VCurrentSlide(0);
        mThread = new Thread(new Runnable() {
            @Override
            public void run() {
                watchCurrentSlide();
            }
        });
    }

    /**
     * Adds a listener for this deckId/presentationId.
     *
     * @param listener notified when the current slide changes
     */
    public void addListener(final DB.CurrentSlideListener listener) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                listener.onChange(mCurrentSlide.getNum());
            }
        });
        mListeners.add(listener);
        if (mListeners.size() == 1) {
            // The first listener was just added.
            Log.i(TAG, "Starting thread");
            mThread.start();
        }
    }

    /**
     * Removes a listener previously added with addListener.  If this was the last
     * listener, no more listeners can be added and the CurrentSlideWatcher
     * should be discarded.
     */
    public void removeListener(DB.CurrentSlideListener listener) {
        mListeners.remove(listener);
        if (mListeners.isEmpty()) {
            mVContext.cancel();
            mThread = null;
            mHandler.removeCallbacksAndMessages(null);
        }
    }

    /**
     * Returns true if the number of listeners is greater than zero.
     */
    public boolean hasListeners() {
        return !mListeners.isEmpty();
    }

    private void notifyListeners(VCurrentSlide slide) {
        Log.i(TAG, "notifyListeners " + slide);
        mCurrentSlide = slide;
        for (DB.CurrentSlideListener listener : mListeners) {
            Log.i(TAG, "notifying listner " + listener);
            listener.onChange(mCurrentSlide.getNum());
        }
    }

    private void watchCurrentSlide() {
        try {
            Log.i(TAG, "watchCurrentSlide");
            String rowKey = NamingUtil.join(mDeckId, mPresentationId, SyncbaseDB.CURRENT_SLIDE);
            BatchDatabase batch = mDB.beginBatch(mVContext, null);
            Table presentations = batch.getTable(SyncbaseDB.PRESENTATIONS_TABLE);
            if (presentations.getRow(rowKey).exists(mVContext)) {
                final VCurrentSlide slide = (VCurrentSlide) presentations.get(
                        mVContext, rowKey, VCurrentSlide.class);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        notifyListeners(slide);
                    }
                });
            }
            Stream<WatchChange> changeStream;
            changeStream = mDB.watch(mVContext, SyncbaseDB.PRESENTATIONS_TABLE, rowKey,
                    batch.getResumeMarker(mVContext));
            for (WatchChange change : changeStream) {
                if (!change.getTableName().equals(SyncbaseDB.PRESENTATIONS_TABLE)) {
                    Log.e(TAG, "Wrong change table name: " + change.getTableName() + ", wanted: " +
                            SyncbaseDB.PRESENTATIONS_TABLE);
                    continue;
                }
                final String key = change.getRowName();
                Log.i(TAG, "Found change " + key);
                if (!key.equals(rowKey)) {
                    Log.d(TAG, "Ignoring change: " + key);
                    continue;
                }
                if (change.getChangeType().equals(ChangeType.PUT_CHANGE)) {
                    final VCurrentSlide slide2 = (VCurrentSlide) VomUtil.decode(
                            change.getVomValue(), VCurrentSlide.class);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            notifyListeners(slide2);
                        }
                    });
                }
            }
        } catch (VException e) {
            Log.e(TAG, "Watching failed " + e);
        }
    }
}
