/*
 * Copyright (C) 2009 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.globalsearch;

import android.app.SearchManager;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.server.search.SearchableInfo;
import android.util.Log;
import android.view.KeyEvent;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

/**
 * Suggestion source that uses the {@link SearchableInfo} of a given component
 * to get suggestions.
 */
public class SearchableSuggestionSource extends AbstractSuggestionSource {

    private static final boolean DBG = false;
    private static final String LOG_TAG = SearchableSuggestionSource.class.getSimpleName();

    private Context mContext;

    private SearchableInfo mSearchable;

    private ActivityInfo mActivityInfo;

    // Flattend name of the searchable activity
    private String mFlattenedComponentName;

    // Prefix for URIs for resources in the package of the searchable activity
    private String mPackageResourceUriPrefix;
    // Prefix for URIs for resources in the package of the suggestion provider.
    private String mProviderResourceUriPrefix;

    // Cached label for the activity
    private String mLabel;

    // Cached icon for the activity
    private String mIcon;
    
    private final boolean mIsWebSuggestionSource;

    // Action key info for KEYCODE_CALL
    private String mCallActionMsg = null;
    private String mCallActionMsgCol = null;

    // A private column the web search source uses to instruct us to pin a result
    // (like "Manage search history") to the bottom of the list when appropriate.
    private static final String SUGGEST_COLUMN_PIN_TO_BOTTOM = "suggest_pin_to_bottom";

    public SearchableSuggestionSource(Context context, SearchableInfo searchable)
            throws NameNotFoundException {
        this(context, searchable, false);
    }

    public SearchableSuggestionSource(Context context, SearchableInfo searchable,
            boolean isWebSuggestionSource) throws NameNotFoundException {
        mContext = context;
        mSearchable = searchable;
        ComponentName componentName = mSearchable.getSearchActivity();
        mFlattenedComponentName = componentName.flattenToShortString();
        mActivityInfo = context.getPackageManager()
                .getActivityInfo(componentName, PackageManager.GET_META_DATA);
        mPackageResourceUriPrefix = "android.resource://" + componentName.getPackageName() + "/";

        // The suggestions may come from a provider different than the activity which contains the
        // searchable (e.g. Music app pointing to the system provided media provider). So find out
        // the provider package and form a resource URI out of it for suggestion icons.
        String suggestProviderPackage = componentName.getPackageName();
        String suggestAuthority = mSearchable.getSuggestAuthority();
        if (suggestAuthority != null) {
            ProviderInfo pi = mContext.getPackageManager().resolveContentProvider(
                    suggestAuthority, 0);
            if (pi != null) suggestProviderPackage = pi.packageName;
        }
        mProviderResourceUriPrefix = "android.resource://" + suggestProviderPackage + "/";

        mLabel = findLabel();
        mIcon = findIcon();
        mIsWebSuggestionSource = isWebSuggestionSource;

        SearchableInfo.ActionKeyInfo actionCall = mSearchable.findActionKey(KeyEvent.KEYCODE_CALL);
        if (actionCall != null) {
            mCallActionMsg = actionCall.getSuggestActionMsg();
            mCallActionMsgCol = actionCall.getSuggestActionMsgColumn();
        }
    }

    /**
     * Gets the Context that this suggestion source runs in.
     */
    public Context getContext() {
        return mContext;
    }

    @Override
    public int getQueryThreshold() {
        return mSearchable.getSuggestThreshold();
    }

    /**
     * Gets the localized, human-readable label for this source.
     */
    public String getLabel() {
        return mLabel;
    }

    /**
     * Gets the icon for this suggestion source as an android.resource: URI.
     */
    public String getIcon() {
        return mIcon;
    }
    
    /**
     * Gets the description to use for this source in system search settings.
     */
    public String getSettingsDescription() {
        return mSearchable.getSettingsDescription();
    }

    /**
     * Gets the name of the activity that this source is for.
     */
    public ComponentName getComponentName() {
        return mSearchable.getSearchActivity();
    }

    @Override
    public boolean isWebSuggestionSource() {
        return mIsWebSuggestionSource;
    }

    @Override
    public SuggestionResult getSuggestions(String query, int maxResults, int queryLimit) {
        Cursor cursor = getCursor(query, queryLimit);
        // Be resilient to non-existent suggestion providers, as the build this is running on
        // is not guaranteed to have anything in particular.
        if (cursor == null) {
            if (DBG) Log.d(LOG_TAG, getComponentName().flattenToShortString() + " returned null");
            return SuggestionResult.createErrorResult(this);
        }

        try {
            // Return without touching the cursor if we have been interrupted. This avoids
            // filling cursor windows and triggering evaluation of lazy cursors.
            if (Thread.interrupted()) {
                if (DBG) Log.d(LOG_TAG, "Interrupted");
                return SuggestionResult.createCancelled(this);
            }

            int count = cursor.getCount();
            if (DBG) {
                Log.d(LOG_TAG, getComponentName().flattenToShortString()
                        + " returned " + count + " suggestions");
            }
            ColumnCachingCursor myCursor = new ColumnCachingCursor(cursor, mCallActionMsgCol);
            ArrayList<SuggestionData> suggestions = new ArrayList<SuggestionData>(count);
            while (cursor.moveToNext() && suggestions.size() < maxResults) {
                if (Thread.interrupted()) {
                    if (DBG) Log.d(LOG_TAG, "Interrupted");
                    return SuggestionResult.createCancelled(this);
                }
                SuggestionData suggestion = makeSuggestion(myCursor);
                if (suggestion != null) {
                    suggestions.add(suggestion);
                }
            }
            return new SuggestionResult(this, suggestions, count, queryLimit);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    /**
     * Gets a Cursor containing suggestions.
     *
     * @param query The query to get suggestions for.
     * @return A Cursor.
     */
    protected Cursor getCursor(String query, int queryLimit) {
        return getSuggestions(getContext(), mSearchable, query, queryLimit);
    }

    /**
     * This is a copy of {@link SearchManager#getSuggestions(SearchableInfo, String)}.
     * The only difference is that it adds "?limit={maxResults}".
     */
    private static Cursor getSuggestions(Context context, SearchableInfo searchable, String query,
            int queryLimit) {
        if (searchable == null) {
            return null;
        }

        String authority = searchable.getSuggestAuthority();
        if (authority == null) {
            return null;
        }

        Uri.Builder uriBuilder = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority);

        // if content path provided, insert it now
        final String contentPath = searchable.getSuggestPath();
        if (contentPath != null) {
            uriBuilder.appendEncodedPath(contentPath);
        }

        // append standard suggestion query path
        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);

        // get the query selection, may be null
        String selection = searchable.getSuggestSelection();
        // inject query, either as selection args or inline
        String[] selArgs = null;
        if (selection != null) {    // use selection if provided
            selArgs = new String[] { query };
        } else {                    // no selection, use REST pattern
            uriBuilder.appendPath(query);
        }

        uriBuilder.appendQueryParameter("limit", String.valueOf(queryLimit));

        Uri uri = uriBuilder
                .fragment("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
                .build();

        // finally, make the query
        if (DBG) {
            Log.d(LOG_TAG, "query(" + uri + ",null," + selection + ","
                    + Arrays.toString(selArgs) + ",null)");
        }
        return context.getContentResolver().query(uri, null, selection, selArgs, null);
    }

    @Override
    protected SuggestionData validateShortcut(SuggestionData shortcut) {
        Cursor cursor = getValidationCursor(shortcut);
        if (cursor == null) return null;
        
        try {
            if (Thread.interrupted()) {
                if (DBG) Log.d(LOG_TAG, "Interrupted");
                return null;
            }
            int count = cursor.getCount();
            if (count == 0) return null;
            if (count > 1) {
                Log.w(LOG_TAG, "received " + count + " results for validation of a single shortcut");
            }
            cursor.moveToNext();
            return makeSuggestion(new ColumnCachingCursor(cursor, mCallActionMsgCol));
        } finally {
          cursor.close();
        }
    }

    protected Cursor getValidationCursor(SuggestionData shortcut) {
        String shortcutId = shortcut.getShortcutId();
        String extraData = shortcut.getIntentExtraData();

        String authority = mSearchable.getSuggestAuthority();
        if (authority == null) {
            return null;
        }

        Uri.Builder uriBuilder = new Uri.Builder()
                .scheme(ContentResolver.SCHEME_CONTENT)
                .authority(authority);

        // if content path provided, insert it now
        final String contentPath = mSearchable.getSuggestPath();
        if (contentPath != null) {
            uriBuilder.appendEncodedPath(contentPath);
        }

        // append the shortcut path and id
        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_SHORTCUT);
        uriBuilder.appendPath(shortcutId);

        Uri uri = uriBuilder
                .appendQueryParameter(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, extraData)
                .fragment("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
                .build();

        // finally, make the query
        return getContext().getContentResolver().query(uri, null, null, null, null);
    }

    /**
     * Builds a suggestion for the current entry in the cursor.
     * The default implementation calls {@link #getTitle(ColumnCachingCursor)} and friends.
     * Subclasses may override this method if overriding the methods for
     * the individual fields is not enough.
     *
     * @return A suggestion, or <code>null</code> if no suggestion can be made
     * from the current record.
     */
    protected SuggestionData makeSuggestion(ColumnCachingCursor cursor) {
        String format = getFormat(cursor);
        String title = getTitle(cursor);
        String description = getDescription(cursor);
        if (description == null) {
            description = "";
        }
        String icon1 = getIcon1(cursor);
        String icon2 = getIcon2(cursor);
        String intentAction = getIntentAction(cursor);
        if (intentAction == null) {
            intentAction = Intent.ACTION_DEFAULT;
        }
        String intentData = getIntentData(cursor);
        String query = getQuery(cursor);
        String actionMsgCall = getActionMsgCall(cursor);
        String intentExtraData = getIntentExtraData(cursor);
        String shortcutId = getShortcutId(cursor);
        boolean pinToBottom = isPinToBottom(cursor);
        boolean spinnerWhileRefreshing = isSpinnerWhileRefreshing(cursor);

        // note: avoiding using SuggestionData.Builder in this case to avoid object allocation, and
        // this is the location where suggestions are created the most.
        return new SuggestionData(
                getComponentName(),
                format,
                title,
                description,
                icon1,
                icon2,
                intentAction,
                intentData,
                query,
                actionMsgCall,
                intentExtraData,
                // The following overwrites any value provided by the searchable since we only
                // direct intents provided by third-party searchables to that searchable activity.
                mFlattenedComponentName,
                shortcutId,
                0,  // background color
                pinToBottom,
                spinnerWhileRefreshing);
    }

    /**
     * Gets the text format.
     *
     * @return The value of the optional {@link SearchManager#SUGGEST_COLUMN_FORMAT} column,
     *         or <code>null</code> if the cursor does not contain that column.
     */
    protected String getFormat(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.FORMAT);
    }

    /**
     * Gets the text to put in the first line of the suggestion for the current entry.
     * Subclasses may want to override this to provide better titles.
     *
     * @return The value of the required {@link SearchManager#SUGGEST_COLUMN_TEXT_1} column.
     */
    protected String getTitle(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.TEXT_1);
    }

    /**
     * Gets the text to put in the second line of the suggestion for the current entry.
     * Subclasses may want to override this to provide better descriptions.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_TEXT_1} column.
     * or <code>null</code> if the cursor does not contain that column.
     */
    protected String getDescription(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.TEXT_2);
    }

    /**
     * Gets the first icon for the current entry (displayed on the left side of
     * the suggestion). This should be a string containing the resource ID or URI
     * of a {@link Drawable}.
     *
     * If no icon was provided in the cursor, the default icon for this searchable
     * (provided by {@link #getIcon()}) will be used.
     *
     * Subclasses may want to override this to provide better icons.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_ICON_1} column,
     * or the value of {@link #getIcon()} if the cursor does not contain that column.
     */
    protected String getIcon1(ColumnCachingCursor cursor) {
        // Get the icon provided in the cursor. If none, get the source's icon.
        String icon = getIcon(cursor, ColumnCachingCursor.ICON_1);
        if (icon == null) {
            icon = getIcon();  // the app's icon
        }
        return icon;
    }

    /**
     * Gets the second icon for the current entry (displayed on the right side of
     * the suggestion). This should be a string containing the resource ID or URI
     * of a {@link Drawable}.
     *
     * Subclasses may want to override this to provide better icons.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_ICON_2} column,
     * or <code>null</code> if the cursor does not contain that column.
     */
    protected String getIcon2(ColumnCachingCursor cursor) {
        return getIcon(cursor, ColumnCachingCursor.ICON_2);
    }

    /**
     * Gets an icon URI from a cursor. If the cursor returns a resource ID,
     * this is converted into an android.resource:// URI.
     */
    protected String getIcon(ColumnCachingCursor cursor, int key) {
        String icon = cursor.getColumnString(key);
        if (icon == null || icon.length() == 0 || "0".equals(icon)) {
            // SearchManager specifies that null or zero can be returned to indicate
            // no icon. We also allow empty string.
            return null;
        } else if (!Character.isDigit(icon.charAt(0))){
            return icon;
        } else {
            return new StringBuilder(mProviderResourceUriPrefix).append(icon).toString();
        }
    }

    /**
     * Gets the intent action for the current entry.
     */
    protected String getIntentAction(ColumnCachingCursor cursor) {
        String intentAction = cursor.getColumnString(ColumnCachingCursor.INTENT_ACTION);
        if (intentAction == null) {
            intentAction = mSearchable.getSuggestIntentAction();
        }
        return intentAction;
    }

    /**
     * Gets the intent data for the current entry. This includes the value of
     * {@link SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID}.
     */
    protected String getIntentData(ColumnCachingCursor cursor) {
        String intentData = cursor.getColumnString(ColumnCachingCursor.INTENT_DATA);
        if (intentData == null) {
            intentData = mSearchable.getSuggestIntentData();
        }
        if (intentData == null) {
            return null;
        }
        String intentDataId = cursor.getColumnString(ColumnCachingCursor.INTENT_DATA_ID);
        return intentDataId == null ? intentData : intentData + "/" + Uri.encode(intentDataId);
    }

    /**
     * Gets the intent extra data for the current entry.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_INTENT_EXTRA_DATA} column,
     * or <code>null</code> if the cursor does not contain that column.
     */
    protected String getIntentExtraData(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.INTENT_EXTRA_DATA);
    }

    /**
     * Gets the search query for the current entry.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_QUERY} column,
     * or <code>null</code> if the cursor does not contain that column.
     */
    protected String getQuery(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.QUERY);
    }

    /**
     * Gets the shortcut id for the current entry.
     *
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} column,
     * or <code>null</code> if the cursor does not contain that column.
     */
    protected String getShortcutId(ColumnCachingCursor cursor) {
        return cursor.getColumnString(ColumnCachingCursor.SHORTCUT_ID);
    }
    
    /**
     * Determines whether this suggestion is a pin-to-bottom suggestion.
     * 
     * @return The value of the {@link #SUGGEST_COLUMN_PIN_TO_BOTTOM} column, or
     * <code>false</code> if the cursor does not contain that column.
     */
    protected boolean isPinToBottom(ColumnCachingCursor cursor) {
        return "true".equals(cursor.getColumnString(ColumnCachingCursor.PIN_TO_BOTTOM));
    }
    
    /**
     * Determines whether this suggestion should show a spinner while refreshing.
     * 
     * @return The value of the {@link SearchManager#SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING}
     * column, or <code>false</code> if the cursor does not contain that column.
     */
    protected boolean isSpinnerWhileRefreshing(ColumnCachingCursor cursor) {
        return "true".equals(cursor.getColumnString(ColumnCachingCursor.SPINNER_WHILE_REFRESHING));
    }

    /**
     * Gets the action message for the CALL key for the current entry.
     */
    protected String getActionMsgCall(ColumnCachingCursor cursor) {
        String suggestActionMsg = cursor.getColumnString(ColumnCachingCursor.ACTION_MSG_CALL);
        if (suggestActionMsg == null) {
            suggestActionMsg = mCallActionMsg;
        }
        return suggestActionMsg;
    }

    private String findLabel() {
        CharSequence label = null;
        PackageManager pm = getContext().getPackageManager();
        // First try the activity label
        int labelRes = mActivityInfo.labelRes;
        if (labelRes != 0) {
            try {
                Resources resources = pm.getResourcesForApplication(mActivityInfo.applicationInfo);
                label = resources.getString(labelRes);
            } catch (NameNotFoundException ex) {
                // shouldn't happen, but if it does, let label remain null
            }
        }
        // Fall back to the application label
        if (label == null) {
            label = pm.getApplicationLabel(mActivityInfo.applicationInfo);
            if (DBG) Log.d(LOG_TAG, getComponentName() + " application label = " + label);
        }
        if (label == null) {
            return null;
        }
        return label.toString();
    }

    private String findIcon() {
        // Try the activity or application icon.
        int iconId = mActivityInfo.getIconResource();
        if (DBG) Log.d(LOG_TAG, getComponentName() + " activity icon = " + iconId);
        // No icon, use default activity icon
        if (iconId == 0) {
            iconId = android.R.drawable.sym_def_app_icon;
        }
        return new StringBuilder(mPackageResourceUriPrefix).append(iconId).toString();
    }

    @Override
    public String toString() {
        return super.toString() + "{component=" + mFlattenedComponentName + "}";
    }

    /**
     * Checks whether this source needs to be invoked after an earlier query returned zero results.
     *
     * @return <code>true</code> if this source needs to be invoked after returning zero results.
     */
    public boolean queryAfterZeroResults() {
        return mSearchable.queryAfterZeroResults();
    }

    /**
     * Wraps a cursor and caches column indexes.
     */
    public static class ColumnCachingCursor extends CursorWrapper {
        // These index into mIndices.
        public static final int FORMAT = 0;
        public static final int TEXT_1 = FORMAT + 1;
        public static final int TEXT_2 = TEXT_1 + 1;
        public static final int ICON_1 = TEXT_2 + 1;
        public static final int ICON_2 = ICON_1 + 1;
        public static final int QUERY = ICON_2 + 1;
        public static final int INTENT_ACTION = QUERY + 1;
        public static final int INTENT_DATA = INTENT_ACTION + 1;
        public static final int INTENT_DATA_ID = INTENT_DATA + 1;
        public static final int INTENT_EXTRA_DATA = INTENT_DATA_ID + 1;
        public static final int SHORTCUT_ID = INTENT_EXTRA_DATA + 1;
        public static final int SPINNER_WHILE_REFRESHING = SHORTCUT_ID + 1;
        public static final int PIN_TO_BOTTOM = SPINNER_WHILE_REFRESHING + 1;
        public static final int ACTION_MSG_CALL = PIN_TO_BOTTOM + 1;
        private static final int KEY_COUNT = ACTION_MSG_CALL + 1;

        // Maps column names to the constants above
        private static final HashMap<String,Integer> mKeys = buildKeys();

        private static HashMap<String,Integer> buildKeys() {
            HashMap<String,Integer> map = new HashMap<String,Integer>();
            map.put(SearchManager.SUGGEST_COLUMN_FORMAT, FORMAT);
            map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, TEXT_1);
            map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, TEXT_2);
            map.put(SearchManager.SUGGEST_COLUMN_ICON_1, ICON_1);
            map.put(SearchManager.SUGGEST_COLUMN_ICON_2, ICON_2);
            map.put(SearchManager.SUGGEST_COLUMN_QUERY, QUERY);
            map.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, INTENT_ACTION);
            map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, INTENT_DATA);
            map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, INTENT_DATA_ID);
            map.put(SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, INTENT_EXTRA_DATA);
            map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, SHORTCUT_ID);
            map.put(SearchManager.SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING,
                    SPINNER_WHILE_REFRESHING);
            map.put(SUGGEST_COLUMN_PIN_TO_BOTTOM, PIN_TO_BOTTOM);
            return map;
        }

        // For each column constant above, this contains the column index in the cursor, or -1.
        private int[] mIndices;

        /**
         * Creates a column index cache.
         *
         * @param cursor A suggestion cursor.
         * @param actionCallColumn The name of the KEYCODE_CALL action column, if any.
         */
        public ColumnCachingCursor(Cursor cursor, String actionCallColumn) {
            super(cursor);
            mIndices = new int[KEY_COUNT];
            Arrays.fill(mIndices, -1);
            String[] columns = cursor.getColumnNames();
            int count = columns.length;
            for (int i = 0; i < count; i++) {
                String col = columns[i];
                if (col == null) continue;
                Integer key = mKeys.get(col);
                if (key == null) {
                    if (col.equals(actionCallColumn)) {
                        mIndices[ACTION_MSG_CALL] = i;
                    }
                } else {
                    mIndices[key] = i;
                }
            }
        }

        /**
         * Gets a column by key.
         *
         * @param key One of the column keys declared in this class.
         * @return A string, or {@code null} if the column is not present.
         */
        public String getColumnString(int key) {
            int col = mIndices[key];
            if (col == -1) {
                return null;
            }
            return getString(col);
        }
    }

}
