// Copyright 2016 The Chromium 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 org.chromium.chrome.browser.ntp.cards;

import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.view.View;
import android.view.ViewGroup;

import org.chromium.base.Callback;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder.PartialBindCallback;
import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
import org.chromium.chrome.browser.ntp.snippets.KnownCategories;
import org.chromium.chrome.browser.ntp.snippets.SectionHeaderViewHolder;
import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder;
import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge;
import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.suggestions.DestructionObserver;
import org.chromium.chrome.browser.suggestions.SuggestionsConfig;
import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView;
import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
import org.chromium.ui.modelutil.ListObservable;

import java.util.List;
import java.util.Set;

/**
 * A class that handles merging above the fold elements and below the fold cards into an adapter
 * that will be used to back the NTP RecyclerView. The first element in the adapter should always be
 * the above-the-fold view (containing the logo, search box, and most visited tiles) and subsequent
 * elements will be the cards shown to the user
 */
public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder>
        implements ListObservable.ListObserver<PartialBindCallback> {
    protected final SuggestionsUiDelegate mUiDelegate;
    protected final ContextMenuManager mContextMenuManager;
    protected final OfflinePageBridge mOfflinePageBridge;

    protected final @Nullable View mAboveTheFoldView;
    protected final UiConfig mUiConfig;
    protected SuggestionsRecyclerView mRecyclerView;

    private final InnerNode<NewTabPageViewHolder, PartialBindCallback> mRoot;

    private final SectionList mSections;
    private final Footer mFooter;

    private final RemoteSuggestionsStatusObserver mRemoteSuggestionsStatusObserver;

    /**
     * Creates the adapter that will manage all the cards to display on the NTP.
     * @param uiDelegate used to interact with the rest of the system.
     * @param aboveTheFoldView the layout encapsulating all the above-the-fold elements
     *         (logo, search box, most visited tiles), or null if only suggestions should
     *         be displayed.
     * @param uiConfig the NTP UI configuration, to be passed to created views.
     * @param offlinePageBridge used to determine if articles are available.
     * @param contextMenuManager used to build context menus.
     */
    public NewTabPageAdapter(SuggestionsUiDelegate uiDelegate, @Nullable View aboveTheFoldView,
            UiConfig uiConfig, OfflinePageBridge offlinePageBridge,
            ContextMenuManager contextMenuManager) {
        mUiDelegate = uiDelegate;
        mContextMenuManager = contextMenuManager;

        mAboveTheFoldView = aboveTheFoldView;
        mUiConfig = uiConfig;
        mRoot = new InnerNode<>();
        mSections = new SectionList(mUiDelegate, offlinePageBridge);

        if (mAboveTheFoldView != null) mRoot.addChildren(new AboveTheFoldItem());
        mRoot.addChildren(mSections);

        mFooter = new Footer();
        mRoot.addChildren(mFooter);

        mOfflinePageBridge = offlinePageBridge;

        mRemoteSuggestionsStatusObserver = new RemoteSuggestionsStatusObserver();
        mUiDelegate.addDestructionObserver(mRemoteSuggestionsStatusObserver);

        updateFooterVisibility();
        mRoot.addObserver(this);
    }

    @Override
    @ItemViewType
    public int getItemViewType(int position) {
        return mRoot.getItemViewType(position);
    }

    @Override
    public NewTabPageViewHolder onCreateViewHolder(ViewGroup parent, @ItemViewType int viewType) {
        assert parent == mRecyclerView;

        switch (viewType) {
            case ItemViewType.ABOVE_THE_FOLD:
                return new NewTabPageViewHolder(mAboveTheFoldView);

            case ItemViewType.HEADER:
                return new SectionHeaderViewHolder(mRecyclerView, mUiConfig);

            case ItemViewType.SNIPPET:
                return new SnippetArticleViewHolder(mRecyclerView, mContextMenuManager, mUiDelegate,
                        mUiConfig, mOfflinePageBridge);

            case ItemViewType.STATUS:
                return new StatusCardViewHolder(mRecyclerView, mContextMenuManager, mUiConfig);

            case ItemViewType.PROGRESS:
                return new ProgressViewHolder(mRecyclerView);

            case ItemViewType.ACTION:
                return new ActionItem.ViewHolder(
                        mRecyclerView, mContextMenuManager, mUiDelegate, mUiConfig);

            case ItemViewType.PROMO:
                return new PersonalizedPromoViewHolder(
                        mRecyclerView, mContextMenuManager, mUiConfig);

            case ItemViewType.FOOTER:
                return new Footer.ViewHolder(mRecyclerView, mUiDelegate.getNavigationDelegate());
        }

        assert false : viewType;
        return null;
    }

    @Override
    public void onBindViewHolder(NewTabPageViewHolder holder, int position, List<Object> payloads) {
        if (payloads == null || payloads.isEmpty()) {
            mRoot.onBindViewHolder(holder, position, null);
            return;
        }

        for (Object payload : payloads) {
            mRoot.onBindViewHolder(holder, position, (PartialBindCallback) payload);
        }
    }

    @Override
    public void onBindViewHolder(NewTabPageViewHolder holder, final int position) {
        onBindViewHolder(holder, position, null);
    }

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

    /** Resets suggestions, pulling the current state as known by the backend. */
    public void refreshSuggestions() {
        mSections.refreshSuggestions();
    }

    public int getFirstHeaderPosition() {
        return getFirstPositionForType(ItemViewType.HEADER);
    }

    public int getFirstCardPosition() {
        for (int i = 0; i < getItemCount(); ++i) {
            if (CardViewHolder.isCard(getItemViewType(i))) return i;
        }
        return RecyclerView.NO_POSITION;
    }

    private void updateFooterVisibility() {
        boolean areRemoteSuggestionsEnabled =
                mUiDelegate.getSuggestionsSource().areRemoteSuggestionsEnabled();
        boolean isArticleSectionVisible = mSections.getSection(KnownCategories.ARTICLES) != null;

        // Always hide footer when in touchless mode since the learn more link will be shown in the
        // context menu.
        mFooter.setVisible(!SuggestionsConfig.scrollToLoad()
                && (areRemoteSuggestionsEnabled || isArticleSectionVisible)
                && SuggestionsConfig.isTouchless());
    }

    private boolean areArticlesLoading() {
        for (int category : mUiDelegate.getSuggestionsSource().getCategories()) {
            if (category != KnownCategories.ARTICLES) continue;

            return mUiDelegate.getSuggestionsSource().getCategoryStatus(KnownCategories.ARTICLES)
                    == CategoryStatus.AVAILABLE_LOADING;
        }
        return false;
    }

    @Override
    public void onItemRangeChanged(ListObservable child, int itemPosition, int itemCount,
            @Nullable PartialBindCallback payload) {
        assert child == mRoot;
        notifyItemRangeChanged(itemPosition, itemCount, payload);
    }

    @Override
    public void onItemRangeInserted(ListObservable child, int itemPosition, int itemCount) {
        assert child == mRoot;
        notifyItemRangeInserted(itemPosition, itemCount);

        updateFooterVisibility();
    }

    @Override
    public void onItemRangeRemoved(ListObservable child, int itemPosition, int itemCount) {
        assert child == mRoot;
        notifyItemRangeRemoved(itemPosition, itemCount);

        updateFooterVisibility();
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        if (mRecyclerView == recyclerView) return;

        // We are assuming for now that the adapter is used with a single RecyclerView.
        // Getting the reference as we are doing here is going to be broken if that changes.
        assert mRecyclerView == null;

        mRecyclerView = (SuggestionsRecyclerView) recyclerView;

        if (SuggestionsConfig.scrollToLoad()) {
            mRecyclerView.setScrollToLoadListener(new ScrollToLoadListener(
                    this, mRecyclerView.getLinearLayoutManager(), mSections));
        }
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);

        if (SuggestionsConfig.scrollToLoad()) mRecyclerView.clearScrollToLoadListener();

        mRecyclerView = null;
    }

    @Override
    public void onViewRecycled(NewTabPageViewHolder holder) {
        holder.recycle();
    }

    /**
     * @return the set of item positions that should be dismissed simultaneously when dismissing the
     *         item at the given {@code position} (including the position itself), or an empty set
     *         if the item can't be dismissed.
     */
    public Set<Integer> getItemDismissalGroup(int position) {
        return mRoot.getItemDismissalGroup(position);
    }

    /**
     * Dismisses the item at the provided adapter position. Can also cause the dismissal of other
     * items or even entire sections.
     * @param position the position of an item to be dismissed.
     * @param itemRemovedCallback
     */
    public void dismissItem(int position, Callback<String> itemRemovedCallback) {
        mRoot.dismissItem(position, itemRemovedCallback);
    }

    private boolean hasAllBeenDismissed() {
        return mSections.isEmpty();
    }

    @VisibleForTesting
    public int getFirstPositionForType(@ItemViewType int viewType) {
        int count = getItemCount();
        for (int i = 0; i < count; i++) {
            if (getItemViewType(i) == viewType) return i;
        }
        return RecyclerView.NO_POSITION;
    }

    @VisibleForTesting
    public SectionList getSectionListForTesting() {
        return mSections;
    }

    @VisibleForTesting
    public InnerNode getRootForTesting() {
        return mRoot;
    }

    @VisibleForTesting
    SuggestionsSource.Observer getSuggestionsSourceObserverForTesting() {
        return mRemoteSuggestionsStatusObserver;
    }

    private class RemoteSuggestionsStatusObserver
            extends SuggestionsSource.EmptyObserver implements DestructionObserver {
        public RemoteSuggestionsStatusObserver() {
            mUiDelegate.getSuggestionsSource().addObserver(this);
        }

        @Override
        public void onCategoryStatusChanged(
                @CategoryInt int category, @CategoryStatus int newStatus) {
            if (!SnippetsBridge.isCategoryRemote(category)) return;

            updateFooterVisibility();
        }

        @Override
        public void onDestroy() {
            mUiDelegate.getSuggestionsSource().removeObserver(this);
        }
    }
}
