/*
 * Copyright (C) 2015 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.contacts.util;

import static com.android.contacts.ShortcutIntentBuilder.INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.provider.ContactsContract.QuickContact;
import android.provider.Settings;
import android.text.TextUtils;

import com.android.contacts.logging.ScreenEvent.ScreenType;
import com.android.contacts.model.account.GoogleAccountType;
import com.android.contacts.quickcontact.QuickContactActivity;

import java.util.List;

/**
 * Utility for forcing intents to be started inside the current app. This is useful for avoiding
 * senseless disambiguation dialogs. Ie, if a user clicks a contact inside Contacts we assume
 * they want to view the contact inside the Contacts app as opposed to a 3rd party contacts app.
 *
 * Methods are designed to replace the use of startActivity() for implicit intents. This class isn't
 * necessary for explicit intents. No attempt is made to replace startActivityForResult(), since
 * startActivityForResult() is always used with explicit intents in this project.
 *
 * Why not just always use explicit intents? The Contacts/Dialer app implements standard intent
 * actions used by others apps. We want to continue exercising these intent filters to make sure
 * they still work. Plus we sometimes don't know an explicit intent would work. See
 * {@link #startActivityInAppIfPossible}.
 *
 * Some ContactsCommon code that is only used by Dialer doesn't use ImplicitIntentsUtil.
 */
public class ImplicitIntentsUtil {

    /**
     * Start an intent. If it is possible for this app to handle the intent, force this app's
     * activity to handle the intent. Sometimes it is impossible to know whether this app
     * can handle an intent while coding since the code is used inside both Dialer and Contacts.
     * This method is particularly useful in such circumstances.
     *
     * On a Nexus 5 with a small number of apps, this method consistently added 3-16ms of delay
     * in order to talk to the package manager.
     */
    public static void startActivityInAppIfPossible(Context context, Intent intent) {
        final Intent appIntent = getIntentInAppIfExists(context, intent);
        if (appIntent != null) {
            context.startActivity(appIntent);
        } else {
            context.startActivity(intent);
        }
    }

    /**
     * Start intent using an activity inside this app. This method is useful if you are certain
     * that the intent can be handled inside this app, and you care about shaving milliseconds.
     */
    public static void startActivityInApp(Context context, Intent intent) {
        String packageName = context.getPackageName();
        intent.setPackage(packageName);
        context.startActivity(intent);
    }

    /**
     * Start an intent normally. Assert that the intent can't be opened inside this app.
     */
    public static void startActivityOutsideApp(Context context, Intent intent) {
        final boolean isPlatformDebugBuild = Build.TYPE.equals("eng")
                || Build.TYPE.equals("userdebug");
        if (isPlatformDebugBuild) {
            if (getIntentInAppIfExists(context, intent) != null) {
                throw new AssertionError("startActivityOutsideApp() was called for an intent" +
                        " that can be handled inside the app");
            }
        }
        context.startActivity(intent);
    }

    /**
     * Starts QuickContact in app with the default mode and specified previous screen type.
     */
    public static void startQuickContact(Activity activity, Uri contactLookupUri,
            int previousScreenType) {
        startQuickContact(activity, contactLookupUri, previousScreenType, /* requestCode */ -1);
    }

    /**
     * Starts QuickContact for result with the default mode and specified previous screen type.
     */
    public static void startQuickContactForResult(Activity activity, Uri contactLookupUri,
            int previousScreenType, int requestCode) {
        startQuickContact(activity, contactLookupUri, previousScreenType, requestCode);
    }

    private static void startQuickContact(Activity activity, Uri contactLookupUri,
            int previousScreenType, int requestCode) {
        final Intent intent = ImplicitIntentsUtil.composeQuickContactIntent(
                activity, contactLookupUri, previousScreenType);

        // We only start "for result" if specifically requested.
        if (requestCode >= 0) {
            intent.setPackage(activity.getPackageName());
            activity.startActivityForResult(intent, requestCode);
        } else {
            startActivityInApp(activity, intent);
        }
    }

    /**
     * Returns an implicit intent for opening QuickContacts with the default mode and specified
     * previous screen type.
     */
    public static Intent composeQuickContactIntent(Context context, Uri contactLookupUri,
            int previousScreenType) {
        return composeQuickContactIntent(context, contactLookupUri,
                QuickContactActivity.MODE_FULLY_EXPANDED, previousScreenType);
    }

    /**
     * Returns an implicit intent for opening QuickContacts.
     */
    public static Intent composeQuickContactIntent(Context context, Uri contactLookupUri,
            int mode, int previousScreenType) {
        final Intent intent = new Intent(context, QuickContactActivity.class);
        intent.setAction(QuickContact.ACTION_QUICK_CONTACT);
        intent.setData(contactLookupUri);
        intent.putExtra(QuickContact.EXTRA_MODE, mode);
        // Make sure not to show QuickContacts on top of another QuickContacts.
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.putExtra(QuickContactActivity.EXTRA_PREVIOUS_SCREEN_TYPE, previousScreenType);
        return intent;
    }

    /**
     * Returns an Intent to open the Settings add account activity filtered to only
     * display contact provider account types.
     */
    public static Intent getIntentForAddingAccount() {
        final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
        intent.putExtra(Settings.EXTRA_AUTHORITIES,
                new String[]{ContactsContract.AUTHORITY});
        return intent;
    }

    /**
     * Returns an Intent to add a google account.
     */
    public static Intent getIntentForAddingGoogleAccount() {
        final Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
        intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES,
                new String[]{GoogleAccountType.ACCOUNT_TYPE});
        return intent;
    }

    public static Intent getIntentForQuickContactLauncherShortcut(Context context, Uri contactUri) {
        final Intent intent = composeQuickContactIntent(context, contactUri,
                QuickContact.MODE_LARGE, ScreenType.UNKNOWN);
        intent.setPackage(context.getPackageName());

        // When starting from the launcher, start in a new, cleared task.
        // CLEAR_WHEN_TASK_RESET cannot reset the root of a task, so we
        // clear the whole thing preemptively here since QuickContactActivity will
        // finish itself when launching other detail activities. We need to use
        // Intent.FLAG_ACTIVITY_NO_ANIMATION since not all versions of launcher will respect
        // the INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION intent extra.
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
                | Intent.FLAG_ACTIVITY_NO_ANIMATION);

        // Tell the launcher to not do its animation, because we are doing our own
        intent.putExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION, true);

        intent.putExtra(QuickContact.EXTRA_EXCLUDE_MIMES, (String[])null);

        return intent;
    }

    /**
     * Returns a copy of {@param intent} with a class name set, if a class inside this app
     * has a corresponding intent filter.
     */
    private static Intent getIntentInAppIfExists(Context context, Intent intent) {
        try {
            final Intent intentCopy = new Intent(intent);
            // Force this intentCopy to open inside the current app.
            intentCopy.setPackage(context.getPackageName());
            final List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(
                    intentCopy, PackageManager.MATCH_DEFAULT_ONLY);
            if (list != null && list.size() != 0) {
                // Now that we know the intentCopy will work inside the current app, we
                // can return this intent non-null.
                if (list.get(0).activityInfo != null
                        && !TextUtils.isEmpty(list.get(0).activityInfo.name)) {
                    // Now that we know the class name, we may as well attach it to intentCopy
                    // to prevent the package manager from needing to find it again inside
                    // startActivity(). This is only needed for efficiency.
                    intentCopy.setClassName(context.getPackageName(),
                            list.get(0).activityInfo.name);
                }
                return intentCopy;
            }
            return null;
        } catch (Exception e) {
            // Don't let the package manager crash our app. If the package manager can't resolve the
            // intent here, then we can still call startActivity without calling setClass() first.
            return null;
        }
    }
}
