/*
 * Copyright (C) 2010 Google Inc.
 * Licensed to 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.mail.browse;

import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.android.mail.R;
import com.android.mail.analytics.Analytics;
import com.android.mail.providers.Account;
import com.android.mail.providers.AccountObserver;
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.MailAppProvider;
import com.android.mail.providers.Settings;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.ConversationColumns;
import com.android.mail.providers.UIProvider.FolderCapabilities;
import com.android.mail.providers.UIProvider.FolderType;
import com.android.mail.ui.ControllableActivity;
import com.android.mail.ui.ConversationCheckedSet;
import com.android.mail.ui.ConversationListCallbacks;
import com.android.mail.ui.ConversationSetObserver;
import com.android.mail.ui.ConversationUpdater;
import com.android.mail.ui.DestructiveAction;
import com.android.mail.ui.FolderOperation;
import com.android.mail.ui.FolderSelectionDialog;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;

import java.util.Collection;
import java.util.List;

/**
 * A component that displays a custom view for an {@code ActionBar}'s {@code
 * ContextMode} specific to operating on a set of conversations.
 */
public class SelectedConversationsActionMenu implements ActionMode.Callback,
        ConversationSetObserver {

    private static final String LOG_TAG = LogTag.getLogTag();

    /**
     * The set of conversations to display the menu for.
     */
    protected final ConversationCheckedSet mCheckedSet;

    private final ControllableActivity mActivity;
    private final ConversationListCallbacks mListController;
    /**
     * Context of the activity. A dialog requires the context of an activity rather than the global
     * root context of the process. So mContext = mActivity.getApplicationContext() will fail.
     */
    private final Context mContext;

    @VisibleForTesting
    private ActionMode mActionMode;

    private boolean mActivated = false;

    /** Object that can update conversation state on our behalf. */
    private final ConversationUpdater mUpdater;

    private Account mAccount;

    private final Folder mFolder;

    private AccountObserver mAccountObserver;

    private MenuItem mDiscardOutboxMenuItem;

    public SelectedConversationsActionMenu(
            ControllableActivity activity, ConversationCheckedSet checkedSet, Folder folder) {
        mActivity = activity;
        mListController = activity.getListHandler();
        mCheckedSet = checkedSet;
        mAccountObserver = new AccountObserver() {
            @Override
            public void onChanged(Account newAccount) {
                mAccount = newAccount;
            }
        };
        mAccount = mAccountObserver.initialize(activity.getAccountController());
        mFolder = folder;
        mContext = mActivity.getActivityContext();
        mUpdater = activity.getConversationUpdater();
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        boolean handled = true;
        // If the user taps a new menu item, commit any existing destructive actions.
        mListController.commitDestructiveActions(true);
        final int itemId = item.getItemId();

        Analytics.getInstance().sendMenuItemEvent(Analytics.EVENT_CATEGORY_MENU_ITEM, itemId,
                "cab_mode", 0);

        UndoCallback undoCallback = null;   // not applicable here (yet)
        if (itemId == R.id.delete) {
            LogUtils.i(LOG_TAG, "Delete selected from CAB menu");
            performDestructiveAction(R.id.delete, undoCallback);
        } else if (itemId == R.id.discard_drafts) {
            LogUtils.i(LOG_TAG, "Discard drafts selected from CAB menu");
            performDestructiveAction(R.id.discard_drafts, undoCallback);
        } else if (itemId == R.id.discard_outbox) {
            LogUtils.i(LOG_TAG, "Discard outbox selected from CAB menu");
            performDestructiveAction(R.id.discard_outbox, undoCallback);
        } else if (itemId == R.id.archive) {
            LogUtils.i(LOG_TAG, "Archive selected from CAB menu");
            performDestructiveAction(R.id.archive, undoCallback);
        } else if (itemId == R.id.remove_folder) {
            destroy(R.id.remove_folder, mCheckedSet.values(),
                    mUpdater.getDeferredRemoveFolder(mCheckedSet.values(), mFolder, true,
                            true, true, undoCallback));
        } else if (itemId == R.id.mute) {
            destroy(R.id.mute, mCheckedSet.values(), mUpdater.getBatchAction(R.id.mute,
                    undoCallback));
        } else if (itemId == R.id.report_spam) {
            destroy(R.id.report_spam, mCheckedSet.values(),
                    mUpdater.getBatchAction(R.id.report_spam, undoCallback));
        } else if (itemId == R.id.mark_not_spam) {
            // Currently, since spam messages are only shown in list with other spam messages,
            // marking a message not as spam is a destructive action
            destroy (R.id.mark_not_spam,
                    mCheckedSet.values(), mUpdater.getBatchAction(R.id.mark_not_spam,
                            undoCallback)) ;
        } else if (itemId == R.id.report_phishing) {
            destroy(R.id.report_phishing,
                    mCheckedSet.values(), mUpdater.getBatchAction(R.id.report_phishing,
                            undoCallback));
        } else if (itemId == R.id.read) {
            markConversationsRead(true);
        } else if (itemId == R.id.unread) {
            markConversationsRead(false);
        } else if (itemId == R.id.star) {
            starConversations(true);
        } else if (itemId == R.id.remove_star) {
            if (mFolder.isType(UIProvider.FolderType.STARRED)) {
                LogUtils.d(LOG_TAG, "We are in a starred folder, removing the star");
                performDestructiveAction(R.id.remove_star, undoCallback);
            } else {
                LogUtils.d(LOG_TAG, "Not in a starred folder.");
                starConversations(false);
            }
        } else if (itemId == R.id.move_to || itemId == R.id.change_folders) {
            boolean cantMove = false;
            Account acct = mAccount;
            // Special handling for virtual folders
            if (mFolder.supportsCapability(FolderCapabilities.IS_VIRTUAL)) {
                Uri accountUri = null;
                for (Conversation conv: mCheckedSet.values()) {
                    if (accountUri == null) {
                        accountUri = conv.accountUri;
                    } else if (!accountUri.equals(conv.accountUri)) {
                        // Tell the user why we can't do this
                        Toast.makeText(mContext, R.string.cant_move_or_change_labels,
                                Toast.LENGTH_LONG).show();
                        cantMove = true;
                        return handled;
                    }
                }
                if (!cantMove) {
                    // Get the actual account here, so that we display its folders in the dialog
                    acct = MailAppProvider.getAccountFromAccountUri(accountUri);
                }
            }
            if (!cantMove) {
                final FolderSelectionDialog dialog = FolderSelectionDialog.getInstance(
                        acct, mCheckedSet.values(), true, mFolder,
                        item.getItemId() == R.id.move_to);
                if (dialog != null) {
                    dialog.show(mActivity.getFragmentManager(), null);
                }
            }
        } else if (itemId == R.id.move_to_inbox) {
            new AsyncTask<Void, Void, Folder>() {
                @Override
                protected Folder doInBackground(final Void... params) {
                    // Get the "move to" inbox
                    return Utils.getFolder(mContext, mAccount.settings.moveToInbox,
                            true /* allowHidden */);
                }

                @Override
                protected void onPostExecute(final Folder moveToInbox) {
                    final List<FolderOperation> ops = Lists.newArrayListWithCapacity(1);
                    // Add inbox
                    ops.add(new FolderOperation(moveToInbox, true));
                    mUpdater.assignFolder(ops, mCheckedSet.values(), true,
                            true /* showUndo */, false /* isMoveTo */);
                }
            }.execute((Void[]) null);
        } else if (itemId == R.id.mark_important) {
            markConversationsImportant(true);
        } else if (itemId == R.id.mark_not_important) {
            if (mFolder.supportsCapability(UIProvider.FolderCapabilities.ONLY_IMPORTANT)) {
                performDestructiveAction(R.id.mark_not_important, undoCallback);
            } else {
                markConversationsImportant(false);
            }
        } else {
            handled = false;
        }
        return handled;
    }

    /**
     * Clear the selection and perform related UI changes to keep the state consistent.
     */
    private void clearChecked() {
        mCheckedSet.clear();
    }

    /**
     * Update the underlying list adapter and redraw the menus if necessary.
     */
    private void updateSelection() {
        mUpdater.refreshConversationList();
        if (mActionMode != null) {
            // Calling mActivity.invalidateOptionsMenu doesn't have the correct behavior, since
            // the action mode is not refreshed when activity's options menu is invalidated.
            // Since we need to refresh our own menu, it is easy to call onPrepareActionMode
            // directly.
            onPrepareActionMode(mActionMode, mActionMode.getMenu());
        }
    }

    private void performDestructiveAction(final int action, UndoCallback undoCallback) {
        final Collection<Conversation> conversations = mCheckedSet.values();
        final Settings settings = mAccount.settings;
        final boolean showDialog;
        // no confirmation dialog by default unless user preference or common sense dictates one
        if (action == R.id.discard_drafts) {
            // drafts are lost forever, so always confirm
            showDialog = true;
        } else if (settings != null && (action == R.id.archive || action == R.id.delete)) {
            showDialog = (action == R.id.delete) ? settings.confirmDelete : settings.confirmArchive;
        } else {
            showDialog = false;
        }
        if (showDialog) {
            mUpdater.makeDialogListener(action, true /* fromSelectedSet */, null /* undoCallback */);
            final int resId;
            if (action == R.id.delete) {
                resId = R.plurals.confirm_delete_conversation;
            } else if (action == R.id.discard_drafts) {
                resId = R.plurals.confirm_discard_drafts_conversation;
            } else {
                resId = R.plurals.confirm_archive_conversation;
            }
            final CharSequence message = Utils.formatPlural(mContext, resId, conversations.size());
            final ConfirmDialogFragment c = ConfirmDialogFragment.newInstance(message);
            c.displayDialog(mActivity.getFragmentManager());
        } else {
            // No need to show the dialog, just make a destructive action and destroy the
            // selected set immediately.
            // TODO(viki): Stop using the deferred action here. Use the registered action.
            destroy(action, conversations, mUpdater.getDeferredBatchAction(action, undoCallback));
        }
    }

    /**
     * Destroy these conversations through the conversation updater
     * @param actionId the ID of the action: R.id.archive, R.id.delete, ...
     * @param target conversations to destroy
     * @param action the action that performs the destruction
     */
    private void destroy(int actionId, final Collection<Conversation> target,
            final DestructiveAction action) {
        LogUtils.i(LOG_TAG, "About to remove %d converations", target.size());
        mUpdater.delete(actionId, target, action, true);
    }

    /**
     * Marks the read state of currently selected conversations (<b>and</b> the backing storage)
     * to the value provided here.
     * @param read is true if the conversations are to be marked as read, false if they are to be
     * marked unread.
     */
    private void markConversationsRead(boolean read) {
        final Collection<Conversation> targets = mCheckedSet.values();
        // The conversations are marked read but not viewed.
        mUpdater.markConversationsRead(targets, read, false);
        updateSelection();
    }

    /**
     * Marks the important state of currently selected conversations (<b>and</b> the backing
     * storage) to the value provided here.
     * @param important is true if the conversations are to be marked as important, false if they
     * are to be marked not important.
     */
    private void markConversationsImportant(boolean important) {
        final Collection<Conversation> target = mCheckedSet.values();
        final int priority = important ? UIProvider.ConversationPriority.HIGH
                : UIProvider.ConversationPriority.LOW;
        mUpdater.updateConversation(target, ConversationColumns.PRIORITY, priority);
        // Update the conversations in the selection too.
        for (final Conversation c : target) {
            c.priority = priority;
        }
        updateSelection();
    }

    /**
     * Marks the selected conversations with the star setting provided here.
     * @param star true if you want all the conversations to have stars, false if you want to remove
     * stars from all conversations
     */
    private void starConversations(boolean star) {
        final Collection<Conversation> target = mCheckedSet.values();
        mUpdater.updateConversation(target, ConversationColumns.STARRED, star);
        // Update the conversations in the selection too.
        for (final Conversation c : target) {
            c.starred = star;
        }
        updateSelection();
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mCheckedSet.addObserver(this);
        final MenuInflater inflater = mActivity.getMenuInflater();
        inflater.inflate(R.menu.conversation_list_selection_actions_menu, menu);
        mActionMode = mode;
        updateCount();
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        // Update the actionbar to select operations available on the current conversation.
        final Collection<Conversation> conversations = mCheckedSet.values();
        boolean showStar = false;
        boolean showMarkUnread = false;
        boolean showMarkImportant = false;
        boolean showMarkNotSpam = false;
        boolean showMarkAsPhishing = false;

        // TODO(shahrk): Clean up these dirty calls using Utils.setMenuItemVisibility(...) or
        // in another way

        for (Conversation conversation : conversations) {
            if (!conversation.starred) {
                showStar = true;
            }
            if (conversation.read) {
                showMarkUnread = true;
            }
            if (!conversation.isImportant()) {
                showMarkImportant = true;
            }
            if (conversation.spam) {
                showMarkNotSpam = true;
            }
            if (!conversation.phishing) {
                showMarkAsPhishing = true;
            }
            if (showStar && showMarkUnread && showMarkImportant && showMarkNotSpam &&
                    showMarkAsPhishing) {
                break;
            }
        }
        final boolean canStar = mFolder != null && !mFolder.isTrash();
        final MenuItem star = menu.findItem(R.id.star);
        star.setVisible(showStar && canStar);
        final MenuItem unstar = menu.findItem(R.id.remove_star);
        unstar.setVisible(!showStar && canStar);
        final MenuItem read = menu.findItem(R.id.read);
        read.setVisible(!showMarkUnread);
        final MenuItem unread = menu.findItem(R.id.unread);
        unread.setVisible(showMarkUnread);
        // We only ever show one of:
        // 1) remove folder
        // 2) archive
        final MenuItem removeFolder = menu.findItem(R.id.remove_folder);
        final MenuItem moveTo = menu.findItem(R.id.move_to);
        final MenuItem moveToInbox = menu.findItem(R.id.move_to_inbox);
        final boolean showRemoveFolder = mFolder != null && mFolder.isType(FolderType.DEFAULT)
                && mFolder.supportsCapability(FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)
                && !mFolder.isProviderFolder()
                && mAccount.supportsCapability(AccountCapabilities.ARCHIVE);
        final boolean showMoveTo = mFolder != null
                && mFolder.supportsCapability(FolderCapabilities.ALLOWS_REMOVE_CONVERSATION);
        final boolean showMoveToInbox = mFolder != null
                && mFolder.supportsCapability(FolderCapabilities.ALLOWS_MOVE_TO_INBOX);
        removeFolder.setVisible(showRemoveFolder);
        moveTo.setVisible(showMoveTo);
        moveToInbox.setVisible(showMoveToInbox);

        final MenuItem changeFolders = menu.findItem(R.id.change_folders);
        changeFolders.setVisible(mAccount.supportsCapability(
                UIProvider.AccountCapabilities.MULTIPLE_FOLDERS_PER_CONV));

        if (mFolder != null && showRemoveFolder) {
            removeFolder.setTitle(mActivity.getActivityContext().getString(R.string.remove_folder,
                    mFolder.name));
        }
        final MenuItem archive = menu.findItem(R.id.archive);
        if (archive != null) {
            archive.setVisible(
                    mAccount.supportsCapability(UIProvider.AccountCapabilities.ARCHIVE) &&
                    mFolder.supportsCapability(FolderCapabilities.ARCHIVE));
        }
        final MenuItem spam = menu.findItem(R.id.report_spam);
        spam.setVisible(!showMarkNotSpam
                && mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_SPAM)
                && mFolder.supportsCapability(FolderCapabilities.REPORT_SPAM));
        final MenuItem notSpam = menu.findItem(R.id.mark_not_spam);
        notSpam.setVisible(showMarkNotSpam &&
                mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_SPAM) &&
                mFolder.supportsCapability(FolderCapabilities.MARK_NOT_SPAM));
        final MenuItem phishing = menu.findItem(R.id.report_phishing);
        phishing.setVisible(showMarkAsPhishing &&
                mAccount.supportsCapability(UIProvider.AccountCapabilities.REPORT_PHISHING) &&
                mFolder.supportsCapability(FolderCapabilities.REPORT_PHISHING));

        final MenuItem mute = menu.findItem(R.id.mute);
        if (mute != null) {
            mute.setVisible(mAccount.supportsCapability(UIProvider.AccountCapabilities.MUTE)
                    && (mFolder != null && mFolder.isInbox()));
        }
        final MenuItem markImportant = menu.findItem(R.id.mark_important);
        markImportant.setVisible(showMarkImportant
                && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
        final MenuItem markNotImportant = menu.findItem(R.id.mark_not_important);
        markNotImportant.setVisible(!showMarkImportant
                && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));

        boolean shouldShowDiscardOutbox = mFolder != null && mFolder.isType(FolderType.OUTBOX);
        mDiscardOutboxMenuItem = menu.findItem(R.id.discard_outbox);
        if (mDiscardOutboxMenuItem != null) {
            mDiscardOutboxMenuItem.setVisible(shouldShowDiscardOutbox);
            mDiscardOutboxMenuItem.setEnabled(shouldEnableDiscardOutbox(conversations));
        }
        final boolean showDelete = mFolder != null && !mFolder.isType(FolderType.OUTBOX)
                && mFolder.supportsCapability(UIProvider.FolderCapabilities.DELETE);
        final MenuItem trash = menu.findItem(R.id.delete);
        trash.setVisible(showDelete);
        // We only want to show the discard drafts menu item if we are not showing the delete menu
        // item, and the current folder is a draft folder and the account supports discarding
        // drafts for a conversation
        final boolean showDiscardDrafts = !showDelete && mFolder != null && mFolder.isDraft() &&
                mAccount.supportsCapability(AccountCapabilities.DISCARD_CONVERSATION_DRAFTS);
        final MenuItem discardDrafts = menu.findItem(R.id.discard_drafts);
        if (discardDrafts != null) {
            discardDrafts.setVisible(showDiscardDrafts);
        }

        return true;
    }

    private boolean shouldEnableDiscardOutbox(Collection<Conversation> conversations) {
        boolean shouldEnableDiscardOutbox = true;
        // Java should be smart enough to realize that once showDiscardOutbox becomes false it can
        // just skip everything remaining in the for-loop..
        for (Conversation conv : conversations) {
            shouldEnableDiscardOutbox &=
                    conv.sendingState != UIProvider.ConversationSendingState.SENDING &&
                    conv.sendingState != UIProvider.ConversationSendingState.RETRYING;
        }
        return shouldEnableDiscardOutbox;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
        // The action mode may have been destroyed due to this menu being deactivated, in which
        // case resources need not be cleaned up. However, if it was destroyed while this menu is
        // active, that implies the user hit "Done" in the top right, and resources need cleaning.
        if (mActivated) {
            destroy();
            // Only commit destructive actions if the user actually pressed
            // done; otherwise, this was handled when we toggled conversation
            // selection state.
            mActivity.getListHandler().commitDestructiveActions(true);
        }
    }

    @Override
    public void onSetPopulated(ConversationCheckedSet set) {
        // Noop. This object can only exist while the set is non-empty.
    }

    @Override
    public void onSetEmpty() {
        LogUtils.d(LOG_TAG, "onSetEmpty called.");
        destroy();
    }

    @Override
    public void onSetChanged(ConversationCheckedSet set) {
        // If the set is empty, the menu buttons are invalid and most like the menu will be cleaned
        // up. Avoid making any changes to stop flickering ("Add Star" -> "Remove Star") just
        // before hiding the menu.
        if (set.isEmpty()) {
            return;
        }
        updateCount();

        if (mFolder.isType(FolderType.OUTBOX) && mDiscardOutboxMenuItem != null) {
            mDiscardOutboxMenuItem.setEnabled(shouldEnableDiscardOutbox(set.values()));
        }
    }

    /**
     * Updates the visible count of how many conversations are selected.
     */
    private void updateCount() {
        if (mActionMode != null) {
            mActionMode.setTitle(Integer.toString(mCheckedSet.size()));
        }
    }

    /**
     * Activates and shows this menu (essentially starting an {@link ActionMode}) if the selected
     * set is non-empty.
     */
    public void activate() {
        if (mCheckedSet.isEmpty()) {
            return;
        }
        mListController.onCabModeEntered();
        mActivated = true;
        if (mActionMode == null) {
            mActivity.startSupportActionMode(this);
        }
    }

    /**
     * De-activates and hides the menu (essentially disabling the {@link ActionMode}), but maintains
     * the selection conversation set, and internally updates state as necessary.
     */
    public void deactivate() {
        mListController.onCabModeExited();
        mActivated = false;
        if (mActionMode != null) {
            mActionMode.finish();
        }
    }

    @VisibleForTesting
    /**
     * Returns true if CAB mode is active.
     */
    public boolean isActivated() {
        return mActivated;
    }

    /**
     * Destroys and cleans up the resources associated with this menu.
     */
    private void destroy() {
        deactivate();
        mCheckedSet.removeObserver(this);
        clearChecked();
        mUpdater.refreshConversationList();
        if (mAccountObserver != null) {
            mAccountObserver.unregisterAndDestroy();
            mAccountObserver = null;
        }
    }
}
