// 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.customtabs;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.view.Menu;
import android.view.MenuItem;

import org.chromium.base.BuildInfo;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate;
import org.chromium.chrome.browser.share.ShareHelper;
import org.chromium.chrome.browser.tab.Tab;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * App menu properties delegate for {@link CustomTabActivity}.
 */
public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegate {
    private static final String SAMPLE_URL = "https://www.google.com";

    private final boolean mShowShare;
    private final boolean mIsMediaViewer;

    private final List<String> mMenuEntries;
    private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>();
    private final AsyncTask<Void, Void, String> mDefaultBrowserFetcher;

    private boolean mIsCustomEntryAdded;

    /**
     * Creates an {@link CustomTabAppMenuPropertiesDelegate} instance.
     */
    public CustomTabAppMenuPropertiesDelegate(final ChromeActivity activity,
            List<String> menuEntries, boolean showShare, final boolean isOpenedByChrome,
            final boolean isMediaViewer) {
        super(activity);
        mMenuEntries = menuEntries;
        mShowShare = showShare;
        mIsMediaViewer = isMediaViewer;

        mDefaultBrowserFetcher = new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                String packageLabel = null;
                if (isOpenedByChrome) {
                    // If the Custom Tab was created by Chrome, Chrome should open it.
                    packageLabel = BuildInfo.getPackageLabel(activity);
                } else {
                    // Check if there is a default handler for the Intent.  If so, grab its label.
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL));
                    PackageManager pm = activity.getPackageManager();
                    ResolveInfo info = pm.resolveActivity(intent, 0);
                    if (info != null && info.match != 0) {
                        packageLabel = info.loadLabel(pm).toString();
                    }
                }

                return packageLabel == null
                        ? activity.getString(R.string.menu_open_in_product_default)
                        : activity.getString(R.string.menu_open_in_product, packageLabel);
            }
        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    @Override
    public void prepareMenu(Menu menu) {
        Tab currentTab = mActivity.getActivityTab();
        if (currentTab != null) {
            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 shareItem = menu.findItem(R.id.share_row_menu_id);
            shareItem.setVisible(mShowShare);
            shareItem.setEnabled(mShowShare);
            if (mShowShare) {
                ShareHelper.configureDirectShareMenuItem(
                        mActivity, menu.findItem(R.id.direct_share_menu_id));
            }

            MenuItem iconRow = menu.findItem(R.id.icon_row_menu_id);
            MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id);
            if (mIsMediaViewer) {
                // Most of the menu items don't make sense when viewing media.
                iconRow.setVisible(false);
                openInChromeItem.setVisible(false);
            } else {
                try {
                    openInChromeItem.setTitle(mDefaultBrowserFetcher.get());
                } catch (InterruptedException | ExecutionException e) {
                    openInChromeItem.setTitle(
                            mActivity.getString(R.string.menu_open_in_product_default));
                }
            }

            // Add custom menu items. Make sure they are only added once.
            if (!mIsCustomEntryAdded) {
                mIsCustomEntryAdded = true;
                for (int i = 0; i < mMenuEntries.size(); i++) {
                    MenuItem item = menu.add(0, 0, 1, mMenuEntries.get(i));
                    mItemToIndexMap.put(item, i);
                }
            }
        }
    }

    /**
     * @return The index that the given menu item should appear in the result of
     *         {@link CustomTabIntentDataProvider#getMenuTitles()}. Returns -1 if item not found.
     */
    public int getIndexOfMenuItem(MenuItem menuItem) {
        if (!mItemToIndexMap.containsKey(menuItem)) {
            return -1;
        }
        return mItemToIndexMap.get(menuItem).intValue();
    }

    @Override
    public int getFooterResourceId() {
        return mIsMediaViewer ? 0 : R.layout.powered_by_chrome_footer;
    }

    /**
     * Get the {@link MenuItem} object associated with the given title. If multiple menu items have
     * the same title, a random one will be returned. This method is for testing purpose _only_.
     */
    @VisibleForTesting
    MenuItem getMenuItemForTitle(String title) {
        for (MenuItem item : mItemToIndexMap.keySet()) {
            if (item.getTitle().equals(title)) return item;
        }
        return null;
    }
}