/*
 * Copyright (C) 2019 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.settings.accessibility;

import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_BUTTON_COMPONENT_NAME;
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
import com.android.settings.core.SubSettingLauncher;
import com.android.settingslib.accessibility.AccessibilityUtils;

import java.util.List;
import java.util.Objects;
import java.util.Set;

public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {

    private final static String TAG = "A11yDetailsSettings";

    @Override
    public int getMetricsCategory() {
        return SettingsEnums.ACCESSIBILITY_DETAILS_SETTINGS;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // In case the Intent doesn't have component name, go to a11y services list.
        final String extraComponentName = getActivity().getIntent().getStringExtra(
                Intent.EXTRA_COMPONENT_NAME);
        if (extraComponentName == null) {
            Log.w(TAG, "Open accessibility services list due to no component name.");
            openAccessibilitySettingsAndFinish();
            return;
        }

        final ComponentName componentName = ComponentName.unflattenFromString(extraComponentName);
        if (openSystemAccessibilitySettingsAndFinish(componentName)) {
            return;
        }

        if (openAccessibilityDetailsSettingsAndFinish(componentName)) {
            return;
        }
        // Fall back to open accessibility services list.
        openAccessibilitySettingsAndFinish();
    }

    private boolean openSystemAccessibilitySettingsAndFinish(
            @Nullable ComponentName componentName) {
        final LaunchFragmentArguments launchArguments =
                getSystemAccessibilitySettingsLaunchArguments(componentName);
        if (launchArguments == null) {
            return false;
        }
        openSubSettings(launchArguments.mDestination, launchArguments.mArguments);
        finish();
        return true;
    }

    @Nullable
    private LaunchFragmentArguments getSystemAccessibilitySettingsLaunchArguments(
            @Nullable ComponentName componentName) {
        if (MAGNIFICATION_COMPONENT_NAME.equals(componentName)) {
            final String destination = ToggleScreenMagnificationPreferenceFragment.class.getName();
            final Bundle arguments = new Bundle();
            MagnificationGesturesPreferenceController.populateMagnificationGesturesPreferenceExtras(
                    arguments, getContext());
            return new LaunchFragmentArguments(destination, arguments);
        }

        if (ACCESSIBILITY_BUTTON_COMPONENT_NAME.equals(componentName)) {
            final String destination = AccessibilityButtonFragment.class.getName();
            return new LaunchFragmentArguments(destination, /* arguments= */ null);
        }

        return null;
    }


    private void openAccessibilitySettingsAndFinish() {
        openSubSettings(AccessibilitySettings.class.getName(), /* arguments= */ null);
        finish();
    }

    private boolean openAccessibilityDetailsSettingsAndFinish(
            @Nullable ComponentName componentName) {
        // In case the A11yServiceInfo doesn't exist, go to ally services list.
        final AccessibilityServiceInfo info = getAccessibilityServiceInfo(componentName);
        if (info == null) {
            Log.w(TAG, "openAccessibilityDetailsSettingsAndFinish : invalid component name.");
            return false;
        }

        // In case this accessibility service isn't permitted, go to a11y services list.
        if (!isServiceAllowed(componentName.getPackageName())) {
            Log.w(TAG,
                    "openAccessibilityDetailsSettingsAndFinish: target accessibility service is"
                            + "prohibited by Device Admin.");
            return false;
        }
        openSubSettings(ToggleAccessibilityServicePreferenceFragment.class.getName(),
                buildArguments(info));
        finish();
        return true;
    }

    private void openSubSettings(@NonNull String destination, @Nullable Bundle arguments) {
        new SubSettingLauncher(getActivity())
                .setDestination(destination)
                .setSourceMetricsCategory(getMetricsCategory())
                .setArguments(arguments)
                .launch();
    }

    @VisibleForTesting
    boolean isServiceAllowed(String packageName) {
        final DevicePolicyManager dpm = getContext().getSystemService(DevicePolicyManager.class);
        final List<String> permittedServices = dpm.getPermittedAccessibilityServices(
                UserHandle.myUserId());
        return (permittedServices == null || permittedServices.contains(packageName));
    }

    private AccessibilityServiceInfo getAccessibilityServiceInfo(ComponentName componentName) {
        if (componentName == null) {
            return null;
        }

        final List<AccessibilityServiceInfo> serviceInfos = AccessibilityManager.getInstance(
                getActivity()).getInstalledAccessibilityServiceList();
        final int serviceInfoCount = serviceInfos.size();
        for (int i = 0; i < serviceInfoCount; i++) {
            AccessibilityServiceInfo serviceInfo = serviceInfos.get(i);
            ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
            if (componentName.getPackageName().equals(resolveInfo.serviceInfo.packageName)
                    && componentName.getClassName().equals(resolveInfo.serviceInfo.name)) {
                return serviceInfo;
            }
        }
        return null;
    }

    private Bundle buildArguments(AccessibilityServiceInfo info) {
        final ResolveInfo resolveInfo = info.getResolveInfo();
        final String title = resolveInfo.loadLabel(getActivity().getPackageManager()).toString();
        final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
        final String packageName = serviceInfo.packageName;
        final ComponentName componentName = new ComponentName(packageName, serviceInfo.name);

        final Set<ComponentName> enabledServices =
                AccessibilityUtils.getEnabledServicesFromSettings(getActivity());
        final boolean serviceEnabled = enabledServices.contains(componentName);
        String description = info.loadDescription(getActivity().getPackageManager());

        if (serviceEnabled && info.crashed) {
            // Update the summaries for services that have crashed.
            description = getString(R.string.accessibility_description_state_stopped);
        }

        final Bundle extras = new Bundle();
        extras.putString(AccessibilitySettings.EXTRA_PREFERENCE_KEY,
                componentName.flattenToString());
        extras.putBoolean(AccessibilitySettings.EXTRA_CHECKED, serviceEnabled);
        extras.putString(AccessibilitySettings.EXTRA_TITLE, title);
        extras.putParcelable(AccessibilitySettings.EXTRA_RESOLVE_INFO, resolveInfo);
        extras.putString(AccessibilitySettings.EXTRA_SUMMARY, description);

        final String settingsClassName = info.getSettingsActivityName();
        if (!TextUtils.isEmpty(settingsClassName)) {
            extras.putString(AccessibilitySettings.EXTRA_SETTINGS_TITLE,
                    getString(R.string.accessibility_menu_item_settings));
            extras.putString(AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME,
                    new ComponentName(packageName, settingsClassName).flattenToString());
        }
        extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName);
        extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes());

        final String htmlDescription = info.loadHtmlDescription(getActivity().getPackageManager());
        extras.putString(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, htmlDescription);
        return extras;
    }

    private void finish() {
        Activity activity = getActivity();
        if (activity == null) {
            return;
        }
        activity.finish();
    }

    private static class LaunchFragmentArguments {
        final String mDestination;
        final Bundle mArguments;
        LaunchFragmentArguments(@NonNull String destination, @Nullable Bundle arguments) {
            mDestination = Objects.requireNonNull(destination);
            mArguments = arguments;
        }
    }
}
