/*
 * 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.cts.verifier.managedprovisioning;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.app.DownloadManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.audiofx.AudioEffect;
import android.net.Uri;
import android.nfc.cardemulation.CardEmulation;
import android.os.Bundle;
import android.os.Environment;
import android.os.UserHandle;
import android.provider.AlarmClock;
import android.provider.CalendarContract.Events;
import android.provider.MediaStore;
import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.widget.Toast;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

/**
 * Helper class for testing if the required cross profile intent filters are set during the
 * managed provisioning.
 */
public class IntentFiltersTestHelper {

    private static final String TAG = "IntentFiltersTestHelper";

    // These are the intents which can be forwarded to the managed profile.
    private static final ArrayList<Intent> forwardedIntentsFromPrimary =
            new ArrayList<>(Arrays.asList(
                new Intent(Intent.ACTION_SEND).setType("*/*"),
                new Intent(Intent.ACTION_SEND_MULTIPLE).setType("*/*")
            ));

    // These are the intents which can be forwarded to the primary profile.
    private static final ArrayList<Intent> forwardedIntentsFromManaged =
            new ArrayList<>(Arrays.asList(
                new Intent(AlarmClock.ACTION_SET_ALARM),
                new Intent(AlarmClock.ACTION_SET_TIMER),
                new Intent(AlarmClock.ACTION_SHOW_ALARMS),
                new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS),
                new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS),
                new Intent(Settings.ACTION_CAPTIONING_SETTINGS),
                new Intent(Settings.ACTION_DATE_SETTINGS),
                new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS),
                new Intent(Settings.ACTION_DISPLAY_SETTINGS),
                new Intent(Settings.ACTION_LOCALE_SETTINGS),
                new Intent(Settings.ACTION_PRIVACY_SETTINGS),
                new Intent(Settings.ACTION_SETTINGS),
                new Intent(Settings.ACTION_WIRELESS_SETTINGS),
                new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
                new Intent("android.net.vpn.SETTINGS"),
                new Intent("android.settings.ACCOUNT_SYNC_SETTINGS"),
                new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
                new Intent("android.settings.LICENSE"),
                new Intent("android.settings.NOTIFICATION_SETTINGS"),
                new Intent("android.settings.USER_SETTINGS"),
                new Intent("android.settings.ZEN_MODE_SETTINGS"),
                new Intent("com.android.settings.ACCESSIBILITY_COLOR_SPACE_SETTINGS"),
                new Intent("com.android.settings.STORAGE_USB_SETTINGS"),
                new Intent("com.android.settings.TTS_SETTINGS"),
                new Intent("com.android.settings.USER_DICTIONARY_EDIT"),
                new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS),
                new Intent(Settings.ACTION_SYNC_SETTINGS),
                new Intent(Settings.ACTION_ADD_ACCOUNT),
                new Intent(Intent.ACTION_GET_CONTENT).setType("*/*").addCategory(
                        Intent.CATEGORY_OPENABLE),
                new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*").addCategory(
                        Intent.CATEGORY_OPENABLE),
                new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
                new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
                new Intent(Settings.ACTION_APPLICATION_SETTINGS)
            ));

    // These are the intents which cannot be forwarded to the primary profile.
    private static final ArrayList<Intent> notForwardedIntentsFromManaged =
            new ArrayList<>(Arrays.asList(
                new Intent(Intent.ACTION_INSERT).setData(
                        Uri.parse("content://browser/bookmarks")),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("http://www.example.com")).addCategory(
                        Intent.CATEGORY_BROWSABLE),
                new Intent(Intent.ACTION_SENDTO).setData(
                        Uri.parse("mailto:user@example.com")),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("mailto:user@example.com")).addCategory(
                        Intent.CATEGORY_BROWSABLE),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("geo:0,0?q=BuckinghamPalace")),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("http://example.com/oceans.mp4")).setType("video/mp4"),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("http://www.example.com/horse.mp3")).setType("audio/*"),
                new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH),
                new Intent(Intent.ACTION_VIEW).setData(
                        Uri.parse("market://details?id=com.android.chrome")).addCategory(
                        Intent.CATEGORY_BROWSABLE),
                new Intent(Intent.ACTION_WEB_SEARCH),
                new Intent(Settings.ACTION_SEARCH_SETTINGS),
                new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE),
                new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
                        Uri.parse("package:com.android.chrome")),
                new Intent(Intent.ACTION_INSERT).setData(Events.CONTENT_URI),
                new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)
            ));

    // This flag specifies we are dealing with intents fired from the primary profile.
    public static final int FLAG_INTENTS_FROM_PRIMARY = 1;
    // This flag specifies we are dealing with intents fired from the managed profile.
    public static final int FLAG_INTENTS_FROM_MANAGED = 2;

    private Context mContext;

    IntentFiltersTestHelper(Context context) {
        mContext = context;

        addIntentsThatDependOnDeviceFeatures();
    }

    private void addIntentsThatDependOnDeviceFeatures() {
        PackageManager pm = mContext.getPackageManager();

        if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:123")),
                    new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:123")),
                    new Intent("android.intent.action.CALL_EMERGENCY").setData(
                            Uri.parse("tel:123")),
                    new Intent("android.intent.action.CALL_PRIVILEGED").setData(
                            Uri.parse("tel:123")),
                    new Intent(Intent.ACTION_VIEW).setData(Uri.parse("tel:123")).addCategory(
                            Intent.CATEGORY_BROWSABLE),
                    new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS),
                    new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS),
                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("sms:07700900100")),
                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("smsto:07700900100")),
                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mms:07700900100")),
                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mmsto:07700900100")),
                    new Intent(Intent.ACTION_VIEW).setData(
                            Uri.parse("sms:07700900100?body=Hello%20world")).addCategory(
                            Intent.CATEGORY_BROWSABLE),
                    new Intent(Intent.ACTION_VIEW).setData(
                            Uri.parse("smsto:07700900100?body=Hello%20world")).addCategory(
                            Intent.CATEGORY_BROWSABLE),
                    new Intent(Intent.ACTION_VIEW).setData(
                            Uri.parse("mms:07700900100?body=Hello%20world")).addCategory(
                            Intent.CATEGORY_BROWSABLE),
                    new Intent(Intent.ACTION_VIEW).setData(
                            Uri.parse("mmsto:07700900100?body=Hello%20world")).addCategory(
                            Intent.CATEGORY_BROWSABLE),
                    new Intent(Settings.ACTION_APN_SETTINGS)));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(Settings.ACTION_NFC_SETTINGS),
                    new Intent(Settings.ACTION_NFCSHARING_SETTINGS),
                    new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS)));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
            forwardedIntentsFromManaged.add(
                    new Intent(CardEmulation.ACTION_CHANGE_DEFAULT));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
                    new Intent(MediaStore.ACTION_VIDEO_CAPTURE),
                    new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA),
                    new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA),
                    new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE),
                    new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)));
        }

        final String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            forwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(Settings.ACTION_WIFI_IP_SETTINGS),
                    new Intent(Settings.ACTION_WIFI_SETTINGS)));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION),
                    new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_LOCATION)) {
            forwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(Settings.ACTION_SOUND_SETTINGS),
                    new Intent("android.settings.ACTION_OTHER_SOUND_SETTINGS")));
            notForwardedIntentsFromManaged.add(
                    new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_HOME_SCREEN)) {
            forwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_HOME_SETTINGS));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
            forwardedIntentsFromManaged.addAll(Arrays.asList(
                    new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS),
                    new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS)));
            notForwardedIntentsFromManaged.add(
                    new Intent("android.settings.SHOW_INPUT_METHOD_PICKER"));
        }

        if (!pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
            forwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_DREAM_SETTINGS));
        }

        if (!pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
            forwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
        }

        if (pm.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
            notForwardedIntentsFromManaged.add(
                    new Intent(Settings.ACTION_PRINT_SETTINGS));
        }
    }

    public boolean checkCrossProfileIntentFilters(int flag) {
        boolean crossProfileIntentFiltersSet;
        if (flag == FLAG_INTENTS_FROM_PRIMARY) {
            crossProfileIntentFiltersSet = checkForIntentsFromPrimary();
        } else {
            crossProfileIntentFiltersSet = checkForIntentsFromManaged();
        }
        return crossProfileIntentFiltersSet;
    }

    /**
     * Checks if required cross profile intent filters are set for the intents fired from the
     * primary profile.
     */
    private boolean checkForIntentsFromPrimary() {
        // Get the class name of the intentForwarderActivity in the primary profile by firing an
        // intent which we know will be forwarded from primary profile to managed profile.
        ActivityInfo forwarderActivityInfo =
                getForwarderActivityInfo(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
        if (forwarderActivityInfo == null) {
            return false;
        }

        // Check for intents which can be forwarded to the managed profile.
        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromPrimary,
                forwarderActivityInfo, true);
        if (intent != null) {
            Log.d(TAG, intent + " from primary profile should be forwarded to the " +
                    "managed profile but is not.");
            return false;
        }

        return true;
    }

    /**
     * Checks if required cross profile intent filters are set for the intents fired from the
     * managed profile.
     */
    private boolean checkForIntentsFromManaged() {
        // Get the class name of the intentForwarderActivity in the managed profile by firing an
        // intent which we know will be forwarded from managed profile to primary profile.
        ActivityInfo forwarderActivityInfo =
                getForwarderActivityInfo(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
        if (forwarderActivityInfo == null) {
            return false;
        }

        // Check for intents which can be forwarded to the primary profile.
        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromManaged,
                forwarderActivityInfo, true);
        if (intent != null) {
            Log.d(TAG, intent + " from managed profile should be forwarded to the " +
                    "primary profile but is not.");
            return false;
        }

        // Check for intents which cannot be forwarded to the primary profile.
        intent = checkForIntentsNotHandled(notForwardedIntentsFromManaged,
                forwarderActivityInfo, false);
        if (intent != null) {
            Log.d(TAG, intent + " from managed profile should not be forwarded to the " +
                    "primary profile but it is.");
            return false;
        }

        return true;
    }

    /**
     * Checks if the intentForwarderActivity can handle the intent passed.
     */
    private boolean canForwarderActivityHandleIntent(Intent intent,
            ActivityInfo forwarderActivityInfo) {
        // Get all the activities which can handle the intent.
        List<ResolveInfo> resolveInfoList =
                mContext.getPackageManager().queryIntentActivities(intent,
                        PackageManager.MATCH_DEFAULT_ONLY);
        // Check if intentForwarderActivity is part of the list.
        for (ResolveInfo resolveInfo : resolveInfoList) {
            if (forwarderActivityInfo.packageName.equals(resolveInfo.activityInfo.packageName)
                    && forwarderActivityInfo.name.equals(resolveInfo.activityInfo.name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the class name of the intentForwarderActivity.
     */
    private ActivityInfo getForwarderActivityInfo(String action) {
        Intent intent = new Intent(action);
        List<ResolveInfo> resolveInfoList =
                mContext.getPackageManager().queryIntentActivities(intent,
                        PackageManager.MATCH_DEFAULT_ONLY);
        if (resolveInfoList.isEmpty() || resolveInfoList.size() > 1) {
            Log.d(TAG, "There should be exactly one activity IntentForwarder which " +
                    "handles the intent " + intent);
            return null;
        }
        return resolveInfoList.get(0).activityInfo;
    }

    /**
     * Checks if the intents passed are correctly handled.
     * @return {@code null} if all the intents are correctly handled
     *         otherwise, the first intent in the list which is not handled correctly.
     */
    private Intent checkForIntentsNotHandled(ArrayList<Intent> intentList,
            ActivityInfo expectedForwarderActivityInfo, boolean canResolve) {
        for (Intent intent : intentList) {
            if (canForwarderActivityHandleIntent(intent,
                    expectedForwarderActivityInfo) != canResolve) {
                return intent;
            }
        }
        return null;
    }
}
