// Copyright 2015 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.appmenu;

import android.content.Context;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;

import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.banners.AppBannerManager;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper;
import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.share.ShareHelper;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.webapk.lib.client.WebApkValidator;

import java.util.concurrent.TimeUnit;

/**
 * App Menu helper that handles hiding and showing menu items based on activity state.
 */
public class AppMenuPropertiesDelegate {
    protected MenuItem mReloadMenuItem;

    protected final ChromeActivity mActivity;

    protected BookmarkBridge mBookmarkBridge;

    public AppMenuPropertiesDelegate(ChromeActivity activity) {
        mActivity = activity;
    }

    /**
     * @return Whether the App Menu should be shown.
     */
    public boolean shouldShowAppMenu() {
        return mActivity.shouldShowAppMenu();
    }

    /**
     * @return Whether the app menu for a web page should be shown.
     */
    public boolean shouldShowPageMenu() {
        boolean isOverview = mActivity.isInOverviewMode();

        if (mActivity.isTablet()) {
            boolean hasTabs = mActivity.getCurrentTabModel().getCount() != 0;
            return hasTabs && !isOverview;
        } else {
            return !isOverview && mActivity.getActivityTab() != null;
        }
    }

    /**
     * Allows the delegate to show and hide items before the App Menu is shown. It is called every
     * time the menu is shown. This assumes that the provided menu contains all the items expected
     * in the application menu (i.e. that the main menu has been inflated into it).
     * @param menu Menu that will be used as the source for the App Menu pop up.
     */
    public void prepareMenu(Menu menu) {
        // Exactly one of these will be true, depending on the type of menu showing.
        boolean isPageMenu = shouldShowPageMenu();
        boolean isOverviewMenu;
        boolean isTabletEmptyModeMenu;

        boolean isOverview = mActivity.isInOverviewMode();
        boolean isIncognito = mActivity.getCurrentTabModel().isIncognito();
        Tab currentTab = mActivity.getActivityTab();

        // Determine which menu to show.
        if (mActivity.isTablet()) {
            boolean hasTabs = mActivity.getCurrentTabModel().getCount() != 0;
            isOverviewMenu = hasTabs && isOverview;
            isTabletEmptyModeMenu = !hasTabs;
        } else {
            isOverviewMenu = isOverview;
            isTabletEmptyModeMenu = false;
        }
        int visibleMenus =
                (isPageMenu ? 1 : 0) + (isOverviewMenu ? 1 : 0) + (isTabletEmptyModeMenu ? 1 : 0);
        assert visibleMenus == 1;

        menu.setGroupVisible(R.id.PAGE_MENU, isPageMenu);
        menu.setGroupVisible(R.id.OVERVIEW_MODE_MENU, isOverviewMenu);
        menu.setGroupVisible(R.id.TABLET_EMPTY_MODE_MENU, isTabletEmptyModeMenu);

        if (isPageMenu && currentTab != null) {
            String url = currentTab.getUrl();
            boolean isChromeScheme = url.startsWith(UrlConstants.CHROME_URL_PREFIX)
                    || url.startsWith(UrlConstants.CHROME_NATIVE_URL_PREFIX);
            boolean isFileScheme = url.startsWith(UrlConstants.FILE_URL_PREFIX);
            boolean isContentScheme = url.startsWith(UrlConstants.CONTENT_URL_PREFIX);
            boolean shouldShowIconRow = !mActivity.isTablet()
                    || mActivity.getWindow().getDecorView().getWidth()
                            < DeviceFormFactor.getMinimumTabletWidthPx(
                                      mActivity.getWindowAndroid().getDisplay());

            boolean bottomToolbarEnabled = mActivity.getToolbarManager() != null
                    && mActivity.getToolbarManager().getBottomToolbarCoordinator() != null;
            shouldShowIconRow &= !bottomToolbarEnabled;

            // Update the icon row items (shown in narrow form factors).
            menu.findItem(R.id.icon_row_menu_id).setVisible(shouldShowIconRow);
            if (shouldShowIconRow) {
                // Disable the "Forward" menu item if there is no page to go to.
                MenuItem forwardMenuItem = menu.findItem(R.id.forward_menu_id);
                forwardMenuItem.setEnabled(currentTab.canGoForward());

                mReloadMenuItem = menu.findItem(R.id.reload_menu_id);
                mReloadMenuItem.setIcon(R.drawable.btn_reload_stop);
                loadingStateChanged(currentTab.isLoading());

                MenuItem bookmarkMenuItem = menu.findItem(R.id.bookmark_this_page_id);
                updateBookmarkMenuItem(bookmarkMenuItem, currentTab);

                MenuItem offlineMenuItem = menu.findItem(R.id.offline_page_id);
                if (offlineMenuItem != null) {
                    offlineMenuItem.setEnabled(
                            DownloadUtils.isAllowedToDownloadPage(currentTab));

                    Drawable drawable = offlineMenuItem.getIcon();
                    if (drawable != null) {
                        int iconTint = ApiCompatibilityUtils.getColor(
                                mActivity.getResources(), R.color.default_icon_color);
                        drawable.mutate();
                        drawable.setColorFilter(iconTint, PorterDuff.Mode.SRC_ATOP);
                    }
                }
            }

            menu.findItem(R.id.update_menu_id).setVisible(
                    UpdateMenuItemHelper.getInstance().shouldShowMenuItem(mActivity));

            boolean hasMoreThanOneTab = mActivity.getTabModelSelector().getTotalTabCount() > 1;
            menu.findItem(R.id.move_to_other_window_menu_id).setVisible(
                    MultiWindowUtils.getInstance().isOpenInOtherWindowSupported(mActivity)
                    && hasMoreThanOneTab);

            MenuItem recentTabsMenuItem = menu.findItem(R.id.recent_tabs_menu_id);
            recentTabsMenuItem.setVisible(!isIncognito);
            recentTabsMenuItem.setTitle(R.string.menu_recent_tabs);

            MenuItem allBookmarksMenuItem = menu.findItem(R.id.all_bookmarks_menu_id);
            allBookmarksMenuItem.setTitle(mActivity.getString(R.string.menu_bookmarks));

            // Don't allow either "chrome://" pages or interstitial pages to be shared.
            menu.findItem(R.id.share_row_menu_id)
                    .setVisible(!isChromeScheme && !currentTab.isShowingInterstitialPage());

            ShareHelper.configureDirectShareMenuItem(
                    mActivity, menu.findItem(R.id.direct_share_menu_id));

            // Disable find in page on the native NTP.
            menu.findItem(R.id.find_in_page_id).setVisible(
                    !currentTab.isNativePage() && currentTab.getWebContents() != null);

            // Hide 'Add to homescreen' for the following:
            // * chrome:// pages - Android doesn't know how to direct those URLs.
            // * incognito pages - To avoid problems where users create shortcuts in incognito
            //                      mode and then open the webapp in regular mode.
            // * file:// - After API 24, file: URIs are not supported in VIEW intents and thus
            //             can not be added to the homescreen.
            // * content:// - Accessing external content URIs requires the calling app to grant
            //                access to the resource via FLAG_GRANT_READ_URI_PERMISSION, and that
            //                is not persisted when adding to the homescreen.
            // * If creating shortcuts it not supported by the current home screen.
            boolean canShowHomeScreenMenuItem = ShortcutHelper.isAddToHomeIntentSupported()
                    && !isChromeScheme && !isFileScheme && !isContentScheme && !isIncognito
                    && !TextUtils.isEmpty(url);
            prepareAddToHomescreenMenuItem(menu, currentTab, canShowHomeScreenMenuItem);

            updateRequestDesktopSiteMenuItem(menu, currentTab, true /* can show */);

            // Only display reader mode settings menu option if the current page is in reader mode.
            menu.findItem(R.id.reader_mode_prefs_id)
                    .setVisible(DomDistillerUrlUtils.isDistilledPage(currentTab.getUrl()));

            // Only display the Enter VR button if VR Shell Dev environment is enabled.
            menu.findItem(R.id.enter_vr_id).setVisible(
                    CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_VR_SHELL_DEV));
        }

        if (isOverviewMenu) {
            if (isIncognito) {
                // Hide normal close all tabs item.
                menu.findItem(R.id.close_all_tabs_menu_id).setVisible(false);
                // Enable close incognito tabs only if there are incognito tabs.
                menu.findItem(R.id.close_all_incognito_tabs_menu_id).setEnabled(true);
            } else {
                // Hide close incognito tabs item.
                menu.findItem(R.id.close_all_incognito_tabs_menu_id).setVisible(false);
                // Enable close all tabs if there are normal tabs or incognito tabs.
                menu.findItem(R.id.close_all_tabs_menu_id).setEnabled(
                        mActivity.getTabModelSelector().getTotalTabCount() > 0);
            }
        }

        // We have to iterate all menu items since same menu item ID may be associated with more
        // than one menu items.
        boolean useAlternativeIncognitoStrings =
                ChromeFeatureList.isEnabled(ChromeFeatureList.INCOGNITO_STRINGS);
        for (int i = 0; i < menu.size(); ++i) {
            MenuItem item = menu.getItem(i);
            if (item.getItemId() == R.id.new_incognito_tab_menu_id) {
                item.setTitle(useAlternativeIncognitoStrings ? R.string.menu_new_private_tab
                                                             : R.string.menu_new_incognito_tab);
            } else if (item.getItemId() == R.id.close_all_incognito_tabs_menu_id) {
                item.setTitle(useAlternativeIncognitoStrings
                                ? R.string.menu_close_all_private_tabs
                                : R.string.menu_close_all_incognito_tabs);
            }
        }

        // Disable new incognito tab when it is blocked (e.g. by a policy).
        // findItem(...).setEnabled(...)" is not enough here, because of the inflated
        // main_menu.xml contains multiple items with the same id in different groups
        // e.g.: new_incognito_tab_menu_id.
        disableEnableMenuItem(menu, R.id.new_incognito_tab_menu_id, true,
                PrefServiceBridge.getInstance().isIncognitoModeEnabled(),
                PrefServiceBridge.getInstance().isIncognitoModeManaged());
        mActivity.prepareMenu(menu);
    }

    /**
     * Sets the visibility and labels of the "Add to Home screen" and "Open WebAPK" menu items.
     */
    protected void prepareAddToHomescreenMenuItem(
            Menu menu, Tab currentTab, boolean canShowHomeScreenMenuItem) {
        // Record whether or not we have finished installability checks for this page when we're
        // preparing the menu to be displayed. This will let us determine if it is feasible to
        // change the add to homescreen menu item based on whether a site is a PWA.
        currentTab.getAppBannerManager().recordMenuOpen();

        MenuItem homescreenItem = menu.findItem(R.id.add_to_homescreen_id);
        MenuItem openWebApkItem = menu.findItem(R.id.open_webapk_id);
        if (canShowHomeScreenMenuItem) {
            Context context = ContextUtils.getApplicationContext();
            long addToHomeScreenStart = SystemClock.elapsedRealtime();
            ResolveInfo resolveInfo =
                    WebApkValidator.queryWebApkResolveInfo(context, currentTab.getUrl());
            RecordHistogram.recordTimesHistogram("Android.PrepareMenu.OpenWebApkVisibilityCheck",
                    SystemClock.elapsedRealtime() - addToHomeScreenStart, TimeUnit.MILLISECONDS);

            boolean openWebApkItemVisible =
                    resolveInfo != null && resolveInfo.activityInfo.packageName != null;

            if (openWebApkItemVisible) {
                String appName = resolveInfo.loadLabel(context.getPackageManager()).toString();
                openWebApkItem.setTitle(context.getString(R.string.menu_open_webapk, appName));

                homescreenItem.setVisible(false);
                openWebApkItem.setVisible(true);
            } else {
                homescreenItem.setTitle(AppBannerManager.getHomescreenLanguageOption());
                homescreenItem.setVisible(true);
                openWebApkItem.setVisible(false);
            }
        } else {
            homescreenItem.setVisible(false);
            openWebApkItem.setVisible(false);
        }
    }

    /**
     * Notify the delegate that the load state changed.
     * @param isLoading Whether the page is currently loading.
     */
    public void loadingStateChanged(boolean isLoading) {
        if (mReloadMenuItem != null) {
            Resources resources = mActivity.getResources();
            mReloadMenuItem.getIcon().setLevel(isLoading
                            ? resources.getInteger(R.integer.reload_button_level_stop)
                            : resources.getInteger(R.integer.reload_button_level_reload));
            mReloadMenuItem.setTitle(isLoading
                    ? R.string.accessibility_btn_stop_loading : R.string.accessibility_btn_refresh);
        }
    }

    /**
     * Notify the delegate that menu was dismissed.
     */
    public void onMenuDismissed() {
        mReloadMenuItem = null;
    }

    // Set enabled to be |enable| for all MenuItems with |id| in |menu|.
    // If |managed| is true then the "Managed By Enterprise" icon is shown next to the menu.
    private void disableEnableMenuItem(
            Menu menu, int id, boolean visible, boolean enabled, boolean managed) {
        for (int i = 0; i < menu.size(); ++i) {
            MenuItem item = menu.getItem(i);
            if (item.getItemId() == id && item.isVisible()) {
                item.setVisible(visible);
                item.setEnabled(enabled);
                if (managed) {
                    item.setIcon(ManagedPreferencesUtils.getManagedByEnterpriseIconId());
                } else {
                    item.setIcon(null);
                }
            }
        }
    }

    /**
     * @return Resource layout id for the footer if there should be one. O otherwise. The footer
     *         is shown at a fixed position at the bottom the app menu. It is always visible and
     *         overlays other app menu items if necessary.
     */
    public int getFooterResourceId() {
        return 0;
    }

    /**
     * @return The resource ID for a layout the be used as the app menu header if there should be
     *         one. 0 otherwise. The header will be displayed as the first item in the app menu. It
     *         will be scrolled off as the menu scrolls.
     */
    public int getHeaderResourceId() {
        return 0;
    }

    /**
     * @return The {@link OnClickListener} to notify when the header view is clicked. May be null if
     *         nothing should happen when the header is clicked.
     */
    @Nullable
    public OnClickListener getHeaderOnClickListener() {
        return null;
    }

    /**
     * Determines whether the footer should be shown based on the maximum available menu height.
     * @param maxMenuHeight The maximum available height for the menu to draw.
     * @return Whether the footer, as specified in {@link #getFooterResourceId()}, should be shown.
     */
    public boolean shouldShowFooter(int maxMenuHeight) {
        return true;
    }

    /**
     * Determines whether the header should be shown based on the maximum available menu height.
     * @param maxMenuHeight The maximum available height for the menu to draw.
     * @return Whether the header, as specified in {@link #getHeaderView()}, should be shown.
     */
    public boolean shouldShowHeader(int maxMenuHeight) {
        return true;
    }

    /**
     * Updates the bookmarks bridge.
     *
     * @param bookmarkBridge The bookmarks bridge.
     */
    public void setBookmarkBridge(BookmarkBridge bookmarkBridge) {
        mBookmarkBridge = bookmarkBridge;
    }

    /**
     * Updates the bookmark item's visibility.
     *
     * @param bookmarkMenuItem {@link MenuItem} for adding/editing the bookmark.
     * @param currentTab        Current tab being displayed.
     */
    protected void updateBookmarkMenuItem(MenuItem bookmarkMenuItem, Tab currentTab) {
        bookmarkMenuItem.setEnabled(mBookmarkBridge.isEditBookmarksEnabled());
        if (currentTab.getBookmarkId() != Tab.INVALID_BOOKMARK_ID) {
            bookmarkMenuItem.setIcon(R.drawable.btn_star_filled);
            bookmarkMenuItem.setChecked(true);
            bookmarkMenuItem.setTitleCondensed(mActivity.getString(R.string.edit_bookmark));
        } else {
            bookmarkMenuItem.setIcon(R.drawable.btn_star);
            bookmarkMenuItem.setChecked(false);
            bookmarkMenuItem.setTitleCondensed(null);
        }
    }

    /**
     * Updates the request desktop site item's state.
     *
     * @param menu {@link Menu} for request desktop site.
     * @param currentTab      Current tab being displayed.
     */
    protected void updateRequestDesktopSiteMenuItem(
            Menu menu, Tab currentTab, boolean canShowRequestDekstopSite) {
        MenuItem requestMenuRow = menu.findItem(R.id.request_desktop_site_row_menu_id);
        MenuItem requestMenuLabel = menu.findItem(R.id.request_desktop_site_id);
        MenuItem requestMenuCheck = menu.findItem(R.id.request_desktop_site_check_id);

        // Hide request desktop site on all chrome:// pages except for the NTP.
        String url = currentTab.getUrl();
        boolean isChromeScheme = url.startsWith(UrlConstants.CHROME_URL_PREFIX)
                || url.startsWith(UrlConstants.CHROME_NATIVE_URL_PREFIX);
        // Also hide request desktop site on Reader Mode.
        boolean isDistilledPage = DomDistillerUrlUtils.isDistilledPage(url);

        boolean itemVisible = canShowRequestDekstopSite
                && (!isChromeScheme || currentTab.isNativePage()) && !isDistilledPage;
        requestMenuRow.setVisible(itemVisible);
        if (!itemVisible) return;

        // Mark the checkbox if RDS is activated on this page.
        requestMenuCheck.setChecked(currentTab.getUseDesktopUserAgent());

        // This title doesn't seem to be displayed by Android, but it is used to set up
        // accessibility text in {@link AppMenuAdapter#setupMenuButton}.
        requestMenuLabel.setTitleCondensed(requestMenuLabel.isChecked()
                        ? mActivity.getString(R.string.menu_request_desktop_site_on)
                        : mActivity.getString(R.string.menu_request_desktop_site_off));
    }

    /**
     * A notification that the header view has finished inflating.
     * @param view The view that was inflated.
     * @param appMenu The menu the view is inside of.
     */
    public void onHeaderViewInflated(AppMenu appMenu, View view) {}

    /**
     * A notification that the footer view has finished inflating.
     * @param view The view that was inflated.
     * @param appMenu The menu the view is inside of.
     */
    public void onFooterViewInflated(AppMenu appMenu, View view) {}
}
