/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.homepage.contextualcards;

import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.DEFERRED_SETUP_VALUE;
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE;

import static java.util.stream.Collectors.groupingBy;

import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.BaseAdapter;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;

import com.android.settings.homepage.contextualcards.conditional.ConditionalCardController;
import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUtils;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * This is a centralized manager of multiple {@link ContextualCardController}.
 *
 * {@link ContextualCardManager} first loads data from {@link ContextualCardLoader} and gets back a
 * list of {@link ContextualCard}. All subclasses of {@link ContextualCardController} are loaded
 * here, which will then trigger the {@link ContextualCardController} to load its data and listen to
 * corresponding changes. When every single {@link ContextualCardController} updates its data, the
 * data will be passed here, then going through some sorting mechanisms. The
 * {@link ContextualCardController} will end up building a list of {@link ContextualCard} for
 * {@link ContextualCardsAdapter} and {@link BaseAdapter#notifyDataSetChanged()} will be called to
 * get the page refreshed.
 */
public class ContextualCardManager implements ContextualCardLoader.CardContentLoaderListener,
        ContextualCardUpdateListener, LifecycleObserver, OnSaveInstanceState {

    @VisibleForTesting
    static final long CARD_CONTENT_LOADER_TIMEOUT_MS = DateUtils.SECOND_IN_MILLIS;
    @VisibleForTesting
    static final String KEY_GLOBAL_CARD_LOADER_TIMEOUT = "global_card_loader_timeout_key";
    @VisibleForTesting
    static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards";

    private static final String TAG = "ContextualCardManager";

    //The list for Settings Custom Card
    private static final int[] SETTINGS_CARDS =
            {ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};

    private final Context mContext;
    private final Lifecycle mLifecycle;
    private final List<LifecycleObserver> mLifecycleObservers;
    private ContextualCardUpdateListener mListener;

    @VisibleForTesting
    final ControllerRendererPool mControllerRendererPool;
    @VisibleForTesting
    final List<ContextualCard> mContextualCards;
    @VisibleForTesting
    long mStartTime;
    @VisibleForTesting
    boolean mIsFirstLaunch;
    @VisibleForTesting
    List<String> mSavedCards;

    public ContextualCardManager(Context context, Lifecycle lifecycle, Bundle savedInstanceState) {
        mContext = context;
        mLifecycle = lifecycle;
        mContextualCards = new ArrayList<>();
        mLifecycleObservers = new ArrayList<>();
        mControllerRendererPool = new ControllerRendererPool();
        mLifecycle.addObserver(this);
        if (savedInstanceState == null) {
            mIsFirstLaunch = true;
            mSavedCards = null;
        } else {
            mSavedCards = savedInstanceState.getStringArrayList(KEY_CONTEXTUAL_CARDS);
        }
        //for data provided by Settings
        for (@ContextualCard.CardType int cardType : SETTINGS_CARDS) {
            setupController(cardType);
        }
    }

    void loadContextualCards(LoaderManager loaderManager) {
        mStartTime = System.currentTimeMillis();
        final CardContentLoaderCallbacks cardContentLoaderCallbacks =
                new CardContentLoaderCallbacks(mContext);
        cardContentLoaderCallbacks.setListener(this);
        // Use the cached data when navigating back to the first page and upon screen rotation.
        loaderManager.initLoader(CARD_CONTENT_LOADER_ID, null /* bundle */,
                cardContentLoaderCallbacks);
    }

    private void loadCardControllers() {
        for (ContextualCard card : mContextualCards) {
            setupController(card.getCardType());
        }
    }

    @VisibleForTesting
    void setupController(@ContextualCard.CardType int cardType) {
        final ContextualCardController controller = mControllerRendererPool.getController(mContext,
                cardType);
        if (controller == null) {
            Log.w(TAG, "Cannot find ContextualCardController for type " + cardType);
            return;
        }
        controller.setCardUpdateListener(this);
        if (controller instanceof LifecycleObserver && !mLifecycleObservers.contains(controller)) {
            mLifecycleObservers.add((LifecycleObserver) controller);
            mLifecycle.addObserver((LifecycleObserver) controller);
        }
    }

    @VisibleForTesting
    List<ContextualCard> sortCards(List<ContextualCard> cards) {
        //take mContextualCards as the source and do the ranking based on the rule.
        return cards.stream()
                .sorted((c1, c2) -> Double.compare(c2.getRankingScore(), c1.getRankingScore()))
                .collect(Collectors.toList());
    }

    @Override
    public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
        final Set<Integer> cardTypes = updateList.keySet();
        //Remove the existing data that matches the certain cardType before inserting new data.
        List<ContextualCard> cardsToKeep;

        // We are not sure how many card types will be in the database, so when the list coming
        // from the database is empty (e.g. no eligible cards/cards are dismissed), we cannot
        // assign a specific card type for its map which is sending here. Thus, we assume that
        // except Conditional cards, all other cards are from the database. So when the map sent
        // here is empty, we only keep Conditional cards.
        if (cardTypes.isEmpty()) {
            final Set<Integer> conditionalCardTypes = new TreeSet() {{
                add(ContextualCard.CardType.CONDITIONAL);
                add(ContextualCard.CardType.CONDITIONAL_HEADER);
                add(ContextualCard.CardType.CONDITIONAL_FOOTER);
            }};
            cardsToKeep = mContextualCards.stream()
                    .filter(card -> conditionalCardTypes.contains(card.getCardType()))
                    .collect(Collectors.toList());
        } else {
            cardsToKeep = mContextualCards.stream()
                    .filter(card -> !cardTypes.contains(card.getCardType()))
                    .collect(Collectors.toList());
        }

        final List<ContextualCard> allCards = new ArrayList<>();
        allCards.addAll(cardsToKeep);
        allCards.addAll(
                updateList.values().stream().flatMap(List::stream).collect(Collectors.toList()));

        //replace with the new data
        mContextualCards.clear();
        final List<ContextualCard> sortedCards = sortCards(allCards);
        mContextualCards.addAll(getCardsWithViewType(sortedCards));

        loadCardControllers();

        if (mListener != null) {
            final Map<Integer, List<ContextualCard>> cardsToUpdate = new ArrayMap<>();
            cardsToUpdate.put(ContextualCard.CardType.DEFAULT, mContextualCards);
            mListener.onContextualCardUpdated(cardsToUpdate);
        }
    }

    @Override
    public void onFinishCardLoading(List<ContextualCard> cards) {
        final long loadTime = System.currentTimeMillis() - mStartTime;
        Log.d(TAG, "Total loading time = " + loadTime);

        final List<ContextualCard> cardsToKeep = getCardsToKeep(cards);

        final MetricsFeatureProvider metricsFeatureProvider =
                FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();

        //navigate back to the homepage, screen rotate or after card dismissal
        if (!mIsFirstLaunch) {
            onContextualCardUpdated(cardsToKeep.stream()
                    .collect(groupingBy(ContextualCard::getCardType)));
            metricsFeatureProvider.action(mContext,
                    SettingsEnums.ACTION_CONTEXTUAL_CARD_SHOW,
                    ContextualCardLogUtils.buildCardListLog(cardsToKeep));
            return;
        }

        final long timeoutLimit = getCardLoaderTimeout();
        if (loadTime <= timeoutLimit) {
            onContextualCardUpdated(cards.stream()
                    .collect(groupingBy(ContextualCard::getCardType)));
            metricsFeatureProvider.action(mContext,
                    SettingsEnums.ACTION_CONTEXTUAL_CARD_SHOW,
                    ContextualCardLogUtils.buildCardListLog(cards));
        } else {
            // log timeout occurrence
            metricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN,
                    SettingsEnums.ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT,
                    SettingsEnums.SETTINGS_HOMEPAGE,
                    null /* key */, (int) loadTime /* value */);
        }
        //only log homepage display upon a fresh launch
        final long totalTime = System.currentTimeMillis() - mStartTime;
        metricsFeatureProvider.action(mContext,
                SettingsEnums.ACTION_CONTEXTUAL_HOME_SHOW, (int) totalTime);

        mIsFirstLaunch = false;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        final ArrayList<String> cards = mContextualCards.stream()
                .map(ContextualCard::getName)
                .collect(Collectors.toCollection(ArrayList::new));

        outState.putStringArrayList(KEY_CONTEXTUAL_CARDS, cards);
    }

    public void onWindowFocusChanged(boolean hasWindowFocus) {
        // Duplicate a list to avoid java.util.ConcurrentModificationException.
        final List<ContextualCard> cards = new ArrayList<>(mContextualCards);
        boolean hasConditionController = false;
        for (ContextualCard card : cards) {
            final ContextualCardController controller = getControllerRendererPool()
                    .getController(mContext, card.getCardType());
            if (controller instanceof ConditionalCardController) {
                hasConditionController = true;
            }
            if (hasWindowFocus && controller instanceof OnStart) {
                ((OnStart) controller).onStart();
            }
            if (!hasWindowFocus && controller instanceof OnStop) {
                ((OnStop) controller).onStop();
            }
        }
        // Conditional cards will always be refreshed whether or not there are conditional cards
        // in the homepage.
        if (!hasConditionController) {
            final ContextualCardController controller = getControllerRendererPool()
                    .getController(mContext, ContextualCard.CardType.CONDITIONAL);
            if (hasWindowFocus && controller instanceof OnStart) {
                ((OnStart) controller).onStart();
            }
            if (!hasWindowFocus && controller instanceof OnStop) {
                ((OnStop) controller).onStop();
            }
        }
    }

    public ControllerRendererPool getControllerRendererPool() {
        return mControllerRendererPool;
    }

    void setListener(ContextualCardUpdateListener listener) {
        mListener = listener;
    }

    @VisibleForTesting
    List<ContextualCard> getCardsWithViewType(List<ContextualCard> cards) {
        if (cards.isEmpty()) {
            return cards;
        }

        final List<ContextualCard> result = getCardsWithDeferredSetupViewType(cards);
        return getCardsWithSuggestionViewType(result);
    }

    @VisibleForTesting
    long getCardLoaderTimeout() {
        // Return the timeout limit if Settings.Global has the KEY_GLOBAL_CARD_LOADER_TIMEOUT key,
        // else return default timeout.
        return Settings.Global.getLong(mContext.getContentResolver(),
                KEY_GLOBAL_CARD_LOADER_TIMEOUT, CARD_CONTENT_LOADER_TIMEOUT_MS);
    }

    private List<ContextualCard> getCardsWithSuggestionViewType(List<ContextualCard> cards) {
        // Shows as half cards if 2 suggestion type of cards are next to each other.
        // Shows as full card if 1 suggestion type of card lives alone.
        final List<ContextualCard> result = new ArrayList<>(cards);
        for (int index = 1; index < result.size(); index++) {
            final ContextualCard previous = result.get(index - 1);
            final ContextualCard current = result.get(index);
            if (current.getCategory() == SUGGESTION_VALUE
                    && previous.getCategory() == SUGGESTION_VALUE) {
                result.set(index - 1, previous.mutate().setViewType(
                        SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH).build());
                result.set(index, current.mutate().setViewType(
                        SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH).build());
                index++;
            }
        }
        return result;
    }

    private List<ContextualCard> getCardsWithDeferredSetupViewType(List<ContextualCard> cards) {
        // Find the deferred setup card and assign it with proper view type.
        // Reason: The returned card list will mix deferred setup card and other suggestion cards
        // after device running 1 days.
        final List<ContextualCard> result = new ArrayList<>(cards);
        for (int index = 0; index < result.size(); index++) {
            final ContextualCard card = cards.get(index);
            if (card.getCategory() == DEFERRED_SETUP_VALUE) {
                result.set(index, card.mutate().setViewType(
                        SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP).build());
                return result;
            }
        }
        return result;
    }

    @VisibleForTesting
    List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) {
        if (mSavedCards != null) {
            //screen rotate
            final List<ContextualCard> cardsToKeep = cards.stream()
                    .filter(card -> mSavedCards.contains(card.getName()))
                    .collect(Collectors.toList());
            mSavedCards = null;
            return cardsToKeep;
        } else {
            //navigate back to the homepage or after dismissing a card
            return cards.stream()
                    .filter(card -> mContextualCards.contains(card))
                    .collect(Collectors.toList());
        }
    }

    static class CardContentLoaderCallbacks implements
            LoaderManager.LoaderCallbacks<List<ContextualCard>> {

        private Context mContext;
        private ContextualCardLoader.CardContentLoaderListener mListener;

        CardContentLoaderCallbacks(Context context) {
            mContext = context.getApplicationContext();
        }

        protected void setListener(ContextualCardLoader.CardContentLoaderListener listener) {
            mListener = listener;
        }

        @NonNull
        @Override
        public Loader<List<ContextualCard>> onCreateLoader(int id, @Nullable Bundle bundle) {
            if (id == CARD_CONTENT_LOADER_ID) {
                return new ContextualCardLoader(mContext);
            } else {
                throw new IllegalArgumentException("Unknown loader id: " + id);
            }
        }

        @Override
        public void onLoadFinished(@NonNull Loader<List<ContextualCard>> loader,
                List<ContextualCard> contextualCards) {
            if (mListener != null) {
                mListener.onFinishCardLoading(contextualCards);
            }
        }

        @Override
        public void onLoaderReset(@NonNull Loader<List<ContextualCard>> loader) {

        }
    }
}
