// 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.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import org.joda.time.DateTime;
import org.joda.time.Period;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import io.v.android.apps.syncslides.R;
import io.v.android.apps.syncslides.model.Deck;
import io.v.android.apps.syncslides.model.DeckFactory;
import io.v.android.apps.syncslides.model.Listener;
import io.v.android.apps.syncslides.model.Question;
import io.v.android.apps.syncslides.model.Slide;

/**
 * A fake implementation of DB for manual testing purposes.
 */
public class FakeDB implements DB {
    private static final int[] SLIDEDRAWABLES = new int[]{
            R.drawable.slide1_thumb,
            R.drawable.slide2_thumb,
            R.drawable.slide3_thumb,
            R.drawable.slide4_thumb,
            R.drawable.slide5_thumb,
            R.drawable.slide6_thumb,
            R.drawable.slide7_thumb,
            R.drawable.slide8_thumb,
            R.drawable.slide9_thumb,
            R.drawable.slide10_thumb,
            R.drawable.slide11_thumb
    };
    private final String[] SLIDENOTES = {
            "This is the teaser slide. It should be memorable and descriptive of what your " +
                    "company is trying to do", "",
            "The bigger the pain, the better",
            "How do you solve this problem? How is it better or different from existing solutions?",
            "Demo the product", "", "[REDACTED]",
            "They may have tractor traction, but we still have the competitive advantage",
            "I'm not a businessman. I'm a business, man", "There is no 'i' on this slide",
            "Sqrt(all evil)"};
    private static final String TAG = "FakeDB";
    private static final int[] DECKTHUMBS = {
            R.drawable.thumb_deck1,
            R.drawable.thumb_deck2,
            R.drawable.thumb_deck3
    };
    private static final String[] DECKTITLES = {"deck 1", "deck 2", "deck 3"};

    private final Handler mHandler;

    private final FakeDeckList mDecks = new FakeDeckList();
    private final Map<String, FakeSlideList> mSlides = new HashMap();

    private List<CurrentSlideListener> mCurrentSlideListeners;
    private Thread mCurrentSlideWatcher;

    private final List<Question> mQuestions;
    private final List<QuestionListener> mQuestionListeners;
    private Thread mQuestionWatcher;

    public FakeDB(Context context) {
        Slide[] slides = new Slide[SLIDEDRAWABLES.length];
        for (int i = 0; i < slides.length; ++i) {
            slides[i] = new FakeSlide(
                    BitmapFactory.decodeResource(context.getResources(), SLIDEDRAWABLES[i]),
                    SLIDENOTES[i]);
        }
        mHandler = new Handler(Looper.getMainLooper());
        for (int i = 0; i < DECKTHUMBS.length; ++i) {
            mDecks.add(DeckFactory.Singleton.get(context).make(
                    DECKTITLES[i], DECKTHUMBS[i], i));
            mSlides.put(String.valueOf(i), new FakeSlideList(slides));
        }
        mCurrentSlideListeners = Lists.newArrayList();
        mCurrentSlideWatcher = new Thread(new Runnable() {
            @Override
            public void run() {
                watchCurrentSlide();
            }
        });
        mCurrentSlideWatcher.start();

        mQuestions = Lists.newArrayList();
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            Question question = new Question(
                    "question" + i,
                    "Questioner #" + i,
                    DateTime.now().minus(Period.minutes(random.nextInt(5)))
                            .toInstant().getMillis());
            mQuestions.add(question);
        }
        mQuestionListeners = Lists.newArrayList();
        mQuestionWatcher = new Thread(new Runnable() {
            @Override
            public void run() {
                watchQuestions();
            }
        });
        mQuestionWatcher.start();
    }

    private static class FakeSlide implements Slide {
        private String mSlideNotes;
        private final Bitmap mSlideImage;

        FakeSlide(Bitmap slideImage, String slideNotes) {
            mSlideImage = slideImage;
            mSlideNotes = slideNotes;
        }

        @Override
        public Bitmap getImage() {
            return mSlideImage;
        }

        @Override
        public String getNotes() {
            return mSlideNotes;
        }

        @Override
        public void setNotes(String notes) {
            mSlideNotes = notes;
        }
    }

    private static class FakeDeckList implements DBList<Deck> {
        private final List<Deck> mDecks = new ArrayList();
        private Listener mListener;

        @Override
        public int getItemCount() {
            return mDecks.size();
        }

        @Override
        public Deck get(int i) {
            return mDecks.get(i);
        }

        @Override
        public void setListener(Listener listener) {
            mListener = listener;
        }

        @Override
        public void discard() {
            // Nothing to do.
        }

        private void add(Deck deck) {
            mDecks.add(deck);
            if (mListener != null) {
                mListener.notifyItemInserted(mDecks.size() - 1);
            }
        }

        private void delete(String deckId) {
            for (int i = 0; i < mDecks.size(); ++i) {
                if (mDecks.get(i).getId().equals(deckId)) {
                    mDecks.remove(i);
                    if (mListener != null) {
                        mListener.notifyItemRemoved(i);
                    }
                    return;
                }
            }
        }
    }

    private static class FakeSlideList implements DBList<Slide> {
        private final List<Slide> mSlides;

        private FakeSlideList(Slide[] slides) {
            // Slides don't currently change, so store them in the ImmutableList.
            mSlides = ImmutableList.<Slide>copyOf(slides);
        }

        @Override
        public int getItemCount() {
            return mSlides.size();
        }

        @Override
        public Slide get(int i) {
            return mSlides.get(i);
        }

        private List<Slide> getSlides() {
            return mSlides;
        }

        @Override
        public void setListener(Listener listener) {
        }

        @Override
        public void discard() {
        }
    }


    @Override
    public void init() {
        // Nothing to do.
    }

    @Override
    public void askQuestion(String deckId, String presentationId, String name) {
        // Nothing to do.
    }

    @Override
    public void handoffQuestion(String deckId, String presentationId, String questionId) {
        // Not implemented.
    }

    @Override
    public void resumeControl(String deckId, String presentationId) {
        // Not implemented.
    }

    @Override
    public void setDriverListener(String deckId, String presentationId, DriverListener listener) {
        // Not implemented.
    }

    @Override
    public void removeDriverListener(String deckId, String presentationId, DriverListener listener) {
        // Not implemented.
    }

    @Override
    public DBList<Deck> getDecks() {
        return mDecks;
    }

    @Override
    public DBList<Slide> getSlides(String deckId) {
        return mSlides.get(deckId);
    }

    public void createPresentation(String deckId, final Callback<CreatePresentationResult> callback) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.done(new CreatePresentationResult("fakePresentationId", "sgname"));
            }
        });
    }

    @Override
    public void joinPresentation(String syncgroupName, final Callback<Void> callback) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.done(null);
            }
        });
    }

    @Override
    public void setCurrentSlide(String deckId, String presentationId, int slideNum) {

    }

    @Override
    public void setSlideNotes(String deckId, int slideNum, String slideNotes) {

     }

    @Override
    public void addCurrentSlideListener(String deckId, String presentationId,
                                        CurrentSlideListener listener) {
        mCurrentSlideListeners.add(listener);
        // TODO(kash): It would be better to fire off a notification of the current
        // slide right away.  That requires storing the current slide in some
        // place that is accessible to the UI thread.  Too much work for now.
    }

    @Override
    public void removeCurrentSlideListener(String deckId, String presentationId,
                                           CurrentSlideListener listener) {
        mCurrentSlideListeners.remove(listener);
    }

    @Override
    public void setQuestionListener(String deckId, String presentationId, QuestionListener listener) {
        mQuestionListeners.add(listener);
    }

    @Override
    public void removeQuestionListener(String deckId, String presentationId, QuestionListener listener) {
        mQuestionListeners.remove(listener);
    }

    @Override
    public void getSlides(String deckId, final Callback<List<Slide>> callback) {
        FakeSlideList list = mSlides.get(deckId);
        final List<Slide> slides = list == null ? null : list.getSlides();
        // Run the callback asynchronously on the UI thread.
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.done(slides);
            }
        });
    }

    @Override
    public void importDeck(Deck deck, Slide[] slides) {
        mDecks.add(deck);
        mSlides.put(deck.getId(), new FakeSlideList(slides));
    }

    @Override
    public void importDeck(final Deck deck,
                           final Slide[] slides,
                           final Callback<Void> callback) {
        new Thread() {
            @Override
            public void run() {
                importDeck(deck, slides);
                if (callback != null) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.done(null);
                        }
                    });
                }
            }
        }.start();
    }

    @Override
    public Deck getDeck(String deckId) {
        for (int i = 0; i < mDecks.getItemCount(); i++) {
            Deck result = mDecks.get(i);
            if (result.getId().equals(deckId)) {
                return result;
            }
        }
        return null;
    }

    @Override
    public void deleteDeck(String deckId) {
        mDecks.delete(deckId);
    }

    @Override
    public void deleteDeck(final String deckId, final Callback<Void> callback) {
        new Thread() {
            @Override
            public void run() {
                deleteDeck(deckId);
                if (callback != null) {
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.done(null);
                        }
                    });
                }
            }
        }.start();
    }

    private void watchCurrentSlide() {
        try {
            int currentSlide = 0;
            while (!Thread.currentThread().isInterrupted()) {
                Thread.sleep(5000);
                // TODO(spetrovic): This assumes all decks have the same # of slides.  Fix it.
                currentSlide = (currentSlide + 1) % SLIDEDRAWABLES.length;
                final int finalCurrentSlide = currentSlide;
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        for (CurrentSlideListener listener : mCurrentSlideListeners) {
                            listener.onChange(finalCurrentSlide);
                        }
                    }
                });
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "Current Slide Watcher interrupted " + e);
        }
    }

    private void watchQuestions() {
        try {
            Random random = new Random();
            while (!Thread.currentThread().isInterrupted()) {
                Thread.sleep(5000);
                Collections.shuffle(mQuestions);
                int numQuestions = random.nextInt(mQuestions.size());
                final List<Question> questions = mQuestions.subList(0, numQuestions);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        for (QuestionListener listener : mQuestionListeners) {
                            listener.onChange(questions);
                        }
                    }
                });
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "Question Watcher interrupted " + e);
        }
    }
}
