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

import static android.provider.Settings.ACTION_WEBVIEW_SETTINGS;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.applications.PackageManagerWrapper;
import com.android.settings.applications.defaultapps.DefaultAppInfo;
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;

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

public class WebViewAppPicker extends DefaultAppPickerFragment {
    private WebViewUpdateServiceWrapper mWebViewUpdateServiceWrapper;

    private WebViewUpdateServiceWrapper getWebViewUpdateServiceWrapper() {
        if (mWebViewUpdateServiceWrapper == null) {
            setWebViewUpdateServiceWrapper(createDefaultWebViewUpdateServiceWrapper());
        }
        return mWebViewUpdateServiceWrapper;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (!mUserManager.isAdminUser()) {
            getActivity().finish();
        }
    }

    @Override
    protected List<DefaultAppInfo> getCandidates() {
        final List<DefaultAppInfo> packageInfoList = new ArrayList<DefaultAppInfo>();
        List<ApplicationInfo> pkgs =
                getWebViewUpdateServiceWrapper().getValidWebViewApplicationInfos(getContext());
        for (ApplicationInfo ai : pkgs) {
            packageInfoList.add(createDefaultAppInfo(mPm, ai,
                    getDisabledReason(getWebViewUpdateServiceWrapper(),
                            getContext(), ai.packageName)));
        }
        return packageInfoList;
    }

    @Override
    protected String getDefaultKey() {
        PackageInfo currentPackage = getWebViewUpdateServiceWrapper().getCurrentWebViewPackage();
        return currentPackage == null ? null : currentPackage.packageName;
    }

    protected boolean setDefaultKey(String key) {
        boolean success = getWebViewUpdateServiceWrapper().setWebViewProvider(key);
        return success;
    }

    @Override
    protected void onSelectionPerformed(boolean success) {
        if (success) {
            Activity activity = getActivity();
            Intent intent = activity == null ? null : activity.getIntent();
            if (intent != null && ACTION_WEBVIEW_SETTINGS.equals(intent.getAction())) {
                // If this was started through ACTION_WEBVIEW_SETTINGS then return once we have
                // chosen a new package.
                getActivity().finish();
            }
        } else {
            getWebViewUpdateServiceWrapper().showInvalidChoiceToast(getActivity());
            updateCandidates();
        }
    }

    private WebViewUpdateServiceWrapper createDefaultWebViewUpdateServiceWrapper() {
        return new WebViewUpdateServiceWrapper();
    }

    @VisibleForTesting
    void setWebViewUpdateServiceWrapper(WebViewUpdateServiceWrapper wvusWrapper) {
        mWebViewUpdateServiceWrapper = wvusWrapper;
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.WEBVIEW_IMPLEMENTATION;
    }

    private static class WebViewAppInfo extends DefaultAppInfo {
        public WebViewAppInfo(PackageManagerWrapper pm, PackageItemInfo packageItemInfo,
                String summary, boolean enabled) {
            super(pm, packageItemInfo, summary, enabled);
        }

        @Override
        public CharSequence loadLabel() {
            String versionName = "";
            try {
                versionName = mPm.getPackageManager().
                        getPackageInfo(packageItemInfo.packageName, 0).versionName;
            } catch (PackageManager.NameNotFoundException e) {
            }
            return String.format("%s %s", super.loadLabel(), versionName);
        }
    }


    @VisibleForTesting
    DefaultAppInfo createDefaultAppInfo(PackageManagerWrapper pm, PackageItemInfo packageItemInfo,
            String disabledReason) {
        return new WebViewAppInfo(pm, packageItemInfo, disabledReason,
                TextUtils.isEmpty(disabledReason) /* enabled */);
    }

    /**
     * Returns the reason why a package cannot be used as WebView implementation.
     * This is either because of it being disabled, uninstalled, or hidden for any user.
     */
    @VisibleForTesting
    String getDisabledReason(WebViewUpdateServiceWrapper webviewUpdateServiceWrapper,
            Context context, String packageName) {
        List<UserPackageWrapper> userPackages =
                webviewUpdateServiceWrapper.getPackageInfosAllUsers(context, packageName);
        for (UserPackageWrapper userPackage : userPackages) {
            if (!userPackage.isInstalledPackage()) {
                // Package uninstalled/hidden
                return context.getString(
                        R.string.webview_uninstalled_for_user, userPackage.getUserInfo().name);
            } else if (!userPackage.isEnabledPackage()) {
                // Package disabled
                return context.getString(
                        R.string.webview_disabled_for_user, userPackage.getUserInfo().name);
            }
        }
        return null;
    }
}
