/*
 * 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.settings.applications;

import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.AUTHORITY;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.COL_GRANTED;
import static android.os.storage.StorageVolume.ScopedAccessProviderContract.TABLE_PERMISSIONS;

import static com.android.settings.applications.AppStateDirectoryAccessBridge.DEBUG;

import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppGlobals;
import android.app.GrantedUriPermission;
import android.app.LoaderManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.util.Log;
import android.util.MutableInt;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
import com.android.settings.widget.ActionButtonPreference;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.applications.ApplicationsState.Callbacks;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.applications.StorageStatsSource.AppStorageStats;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;

public class AppStorageSettings extends AppInfoWithHeader
        implements OnClickListener, Callbacks, DialogInterface.OnClickListener,
        LoaderManager.LoaderCallbacks<AppStorageStats> {
    private static final String TAG = AppStorageSettings.class.getSimpleName();

    //internal constants used in Handler
    private static final int OP_SUCCESSFUL = 1;
    private static final int OP_FAILED = 2;
    private static final int MSG_CLEAR_USER_DATA = 1;
    private static final int MSG_CLEAR_CACHE = 3;

    // invalid size value used initially and also when size retrieval through PackageManager
    // fails for whatever reason
    private static final int SIZE_INVALID = -1;

    // Result code identifiers
    public static final int REQUEST_MANAGE_SPACE = 2;

    private static final int DLG_CLEAR_DATA = DLG_BASE + 1;
    private static final int DLG_CANNOT_CLEAR_DATA = DLG_BASE + 2;

    private static final String KEY_STORAGE_USED = "storage_used";
    private static final String KEY_CHANGE_STORAGE = "change_storage_button";
    private static final String KEY_STORAGE_SPACE = "storage_space";
    private static final String KEY_STORAGE_CATEGORY = "storage_category";

    private static final String KEY_TOTAL_SIZE = "total_size";
    private static final String KEY_APP_SIZE = "app_size";
    private static final String KEY_DATA_SIZE = "data_size";
    private static final String KEY_CACHE_SIZE = "cache_size";

    private static final String KEY_HEADER_BUTTONS = "header_view";

    private static final String KEY_URI_CATEGORY = "uri_category";
    private static final String KEY_CLEAR_URI = "clear_uri_button";

    private static final String KEY_CACHE_CLEARED = "cache_cleared";
    private static final String KEY_DATA_CLEARED = "data_cleared";

    // Views related to cache info
    @VisibleForTesting
    ActionButtonPreference mButtonsPref;

    private Preference mStorageUsed;
    private Button mChangeStorageButton;

    // Views related to URI permissions
    private Button mClearUriButton;
    private LayoutPreference mClearUri;
    private PreferenceCategory mUri;

    private boolean mCanClearData = true;
    private boolean mCacheCleared;
    private boolean mDataCleared;

    @VisibleForTesting
    AppStorageSizesController mSizeController;

    private ClearCacheObserver mClearCacheObserver;
    private ClearUserDataObserver mClearDataObserver;

    private VolumeInfo[] mCandidates;
    private AlertDialog.Builder mDialogBuilder;
    private ApplicationInfo mInfo;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            mCacheCleared = savedInstanceState.getBoolean(KEY_CACHE_CLEARED, false);
            mDataCleared = savedInstanceState.getBoolean(KEY_DATA_CLEARED, false);
            mCacheCleared = mCacheCleared || mDataCleared;
        }

        addPreferencesFromResource(R.xml.app_storage_settings);
        setupViews();
        initMoveDialog();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateSize();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(KEY_CACHE_CLEARED, mCacheCleared);
        outState.putBoolean(KEY_DATA_CLEARED, mDataCleared);
    }

    private void setupViews() {
        // Set default values on sizes
        mSizeController = new AppStorageSizesController.Builder()
                .setTotalSizePreference(findPreference(KEY_TOTAL_SIZE))
                .setAppSizePreference(findPreference(KEY_APP_SIZE))
                .setDataSizePreference(findPreference(KEY_DATA_SIZE))
                .setCacheSizePreference(findPreference(KEY_CACHE_SIZE))
                .setComputingString(R.string.computing_size)
                .setErrorString(R.string.invalid_size_value)
                .build();
        mButtonsPref = ((ActionButtonPreference) findPreference(KEY_HEADER_BUTTONS))
                .setButton1Positive(false)
                .setButton2Positive(false);

        mStorageUsed = findPreference(KEY_STORAGE_USED);
        mChangeStorageButton = (Button) ((LayoutPreference) findPreference(KEY_CHANGE_STORAGE))
                .findViewById(R.id.button);
        mChangeStorageButton.setText(R.string.change);
        mChangeStorageButton.setOnClickListener(this);

        // Cache section
        mButtonsPref.setButton2Text(R.string.clear_cache_btn_text);

        // URI permissions section
        mUri = (PreferenceCategory) findPreference(KEY_URI_CATEGORY);
        mClearUri = (LayoutPreference) mUri.findPreference(KEY_CLEAR_URI);
        mClearUriButton = (Button) mClearUri.findViewById(R.id.button);
        mClearUriButton.setText(R.string.clear_uri_btn_text);
        mClearUriButton.setOnClickListener(this);
    }

    @VisibleForTesting
    void handleClearCacheClick() {
        if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                    getActivity(), mAppsControlDisallowedAdmin);
            return;
        } else if (mClearCacheObserver == null) { // Lazy initialization of observer
            mClearCacheObserver = new ClearCacheObserver();
        }
        mMetricsFeatureProvider.action(getContext(),
                MetricsEvent.ACTION_SETTINGS_CLEAR_APP_CACHE);
        mPm.deleteApplicationCacheFiles(mPackageName, mClearCacheObserver);
    }

    @VisibleForTesting
    void handleClearDataClick() {
        if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
            RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                    getActivity(), mAppsControlDisallowedAdmin);
        } else if (mAppEntry.info.manageSpaceActivityName != null) {
            if (!Utils.isMonkeyRunning()) {
                Intent intent = new Intent(Intent.ACTION_DEFAULT);
                intent.setClassName(mAppEntry.info.packageName,
                        mAppEntry.info.manageSpaceActivityName);
                startActivityForResult(intent, REQUEST_MANAGE_SPACE);
            }
        } else {
            showDialogInner(DLG_CLEAR_DATA, 0);
        }
    }

    @Override
    public void onClick(View v) {
        if (v == mChangeStorageButton && mDialogBuilder != null && !isMoveInProgress()) {
            mDialogBuilder.show();
        } else if (v == mClearUriButton) {
            if (mAppsControlDisallowedAdmin != null && !mAppsControlDisallowedBySystem) {
                RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
                        getActivity(), mAppsControlDisallowedAdmin);
            } else {
                clearUriPermissions();
            }
        }
    }

    private boolean isMoveInProgress() {
        try {
            // TODO: define a cleaner API for this
            AppGlobals.getPackageManager().checkPackageStartable(mPackageName,
                    UserHandle.myUserId());
            return false;
        } catch (RemoteException | SecurityException e) {
            return true;
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        final Context context = getActivity();

        // If not current volume, kick off move wizard
        final VolumeInfo targetVol = mCandidates[which];
        final VolumeInfo currentVol = context.getPackageManager().getPackageCurrentVolume(
                mAppEntry.info);
        if (!Objects.equals(targetVol, currentVol)) {
            final Intent intent = new Intent(context, StorageWizardMoveConfirm.class);
            intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, targetVol.getId());
            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
            startActivity(intent);
        }
        dialog.dismiss();
    }

    @Override
    protected boolean refreshUi() {
        retrieveAppEntry();
        if (mAppEntry == null) {
            return false;
        }
        updateUiWithSize(mSizeController.getLastResult());
        refreshGrantedUriPermissions();

        final VolumeInfo currentVol = getActivity().getPackageManager()
                .getPackageCurrentVolume(mAppEntry.info);
        final StorageManager storage = getContext().getSystemService(StorageManager.class);
        mStorageUsed.setSummary(storage.getBestVolumeDescription(currentVol));

        refreshButtons();

        return true;
    }

    private void refreshButtons() {
        initMoveDialog();
        initDataButtons();
    }

    private void initDataButtons() {
        final boolean appHasSpaceManagementUI = mAppEntry.info.manageSpaceActivityName != null;
        final boolean appHasActiveAdmins = mDpm.packageHasActiveAdmins(mPackageName);
        // Check that SYSTEM_APP flag is set, and ALLOW_CLEAR_USER_DATA is not set.
        final boolean isNonClearableSystemApp =
                (mAppEntry.info.flags & (FLAG_SYSTEM | FLAG_ALLOW_CLEAR_USER_DATA)) == FLAG_SYSTEM;
        final boolean appRestrictsClearingData = isNonClearableSystemApp || appHasActiveAdmins;

        final Intent intent = new Intent(Intent.ACTION_DEFAULT);
        if (appHasSpaceManagementUI) {
            intent.setClassName(mAppEntry.info.packageName, mAppEntry.info.manageSpaceActivityName);
        }
        final boolean isManageSpaceActivityAvailable =
                getPackageManager().resolveActivity(intent, 0) != null;

        if ((!appHasSpaceManagementUI && appRestrictsClearingData)
                || !isManageSpaceActivityAvailable) {
            mButtonsPref
                    .setButton1Text(R.string.clear_user_data_text)
                    .setButton1Enabled(false);
            mCanClearData = false;
        } else {
            if (appHasSpaceManagementUI) {
                mButtonsPref.setButton1Text(R.string.manage_space_text);
            } else {
                mButtonsPref.setButton1Text(R.string.clear_user_data_text);
            }
            mButtonsPref
                    .setButton1Text(R.string.clear_user_data_text)
                    .setButton1OnClickListener(v -> handleClearDataClick());
        }

        if (mAppsControlDisallowedBySystem) {
            mButtonsPref.setButton1Enabled(false);
        }
    }

    private void initMoveDialog() {
        final Context context = getActivity();
        final StorageManager storage = context.getSystemService(StorageManager.class);

        final List<VolumeInfo> candidates = context.getPackageManager()
                .getPackageCandidateVolumes(mAppEntry.info);
        if (candidates.size() > 1) {
            Collections.sort(candidates, VolumeInfo.getDescriptionComparator());

            CharSequence[] labels = new CharSequence[candidates.size()];
            int current = -1;
            for (int i = 0; i < candidates.size(); i++) {
                final String volDescrip = storage.getBestVolumeDescription(candidates.get(i));
                if (Objects.equals(volDescrip, mStorageUsed.getSummary())) {
                    current = i;
                }
                labels[i] = volDescrip;
            }
            mCandidates = candidates.toArray(new VolumeInfo[candidates.size()]);
            mDialogBuilder = new AlertDialog.Builder(getContext())
                    .setTitle(R.string.change_storage)
                    .setSingleChoiceItems(labels, current, this)
                    .setNegativeButton(R.string.cancel, null);
        } else {
            removePreference(KEY_STORAGE_USED);
            removePreference(KEY_CHANGE_STORAGE);
            removePreference(KEY_STORAGE_SPACE);
        }
    }

    /*
     * Private method to initiate clearing user data when the user clicks the clear data
     * button for a system package
     */
    private void initiateClearUserData() {
        mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_SETTINGS_CLEAR_APP_DATA);
        mButtonsPref.setButton1Enabled(false);
        // Invoke uninstall or clear user data based on sysPackage
        String packageName = mAppEntry.info.packageName;
        Log.i(TAG, "Clearing user data for package : " + packageName);
        if (mClearDataObserver == null) {
            mClearDataObserver = new ClearUserDataObserver();
        }
        ActivityManager am = (ActivityManager)
                getActivity().getSystemService(Context.ACTIVITY_SERVICE);
        boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
        if (!res) {
            // Clearing data failed for some obscure reason. Just log error for now
            Log.i(TAG, "Couldn't clear application user data for package:" + packageName);
            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
        } else {
            mButtonsPref.setButton1Text(R.string.recompute_size);
        }
    }

    /*
     * Private method to handle clear message notification from observer when
     * the async operation from PackageManager is complete
     */
    private void processClearMsg(Message msg) {
        int result = msg.arg1;
        String packageName = mAppEntry.info.packageName;
        mButtonsPref.setButton1Text(R.string.clear_user_data_text);
        if (result == OP_SUCCESSFUL) {
            Log.i(TAG, "Cleared user data for package : " + packageName);
            updateSize();
        } else {
            mButtonsPref.setButton1Enabled(true);
        }
    }

    private void refreshGrantedUriPermissions() {
        // Clear UI first (in case the activity has been resumed)
        removeUriPermissionsFromUi();

        // Gets all URI permissions from am.
        ActivityManager am = (ActivityManager) getActivity().getSystemService(
                Context.ACTIVITY_SERVICE);
        List<GrantedUriPermission> perms =
                am.getGrantedUriPermissions(mAppEntry.info.packageName).getList();

        if (perms.isEmpty()) {
            mClearUriButton.setVisibility(View.GONE);
            return;
        }

        PackageManager pm = getActivity().getPackageManager();

        // Group number of URIs by app.
        Map<CharSequence, MutableInt> uriCounters = new TreeMap<>();
        for (GrantedUriPermission perm : perms) {
            String authority = perm.uri.getAuthority();
            ProviderInfo provider = pm.resolveContentProvider(authority, 0);
            CharSequence app = provider.applicationInfo.loadLabel(pm);
            MutableInt count = uriCounters.get(app);
            if (count == null) {
                uriCounters.put(app, new MutableInt(1));
            } else {
                count.value++;
            }
        }

        // Dynamically add the preferences, one per app.
        int order = 0;
        for (Map.Entry<CharSequence, MutableInt> entry : uriCounters.entrySet()) {
            int numberResources = entry.getValue().value;
            Preference pref = new Preference(getPrefContext());
            pref.setTitle(entry.getKey());
            pref.setSummary(getPrefContext().getResources()
                    .getQuantityString(R.plurals.uri_permissions_text, numberResources,
                            numberResources));
            pref.setSelectable(false);
            pref.setLayoutResource(R.layout.horizontal_preference);
            pref.setOrder(order);
            Log.v(TAG, "Adding preference '" + pref + "' at order " + order);
            mUri.addPreference(pref);
        }

        if (mAppsControlDisallowedBySystem) {
            mClearUriButton.setEnabled(false);
        }

        mClearUri.setOrder(order);
        mClearUriButton.setVisibility(View.VISIBLE);

    }

    private void clearUriPermissions() {
        final Context context = getActivity();
        final String packageName = mAppEntry.info.packageName;
        // Synchronously revoke the permissions.
        final ActivityManager am = (ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE);
        am.clearGrantedUriPermissions(packageName);


        // Also update the Scoped Directory Access UI permissions
        final Uri providerUri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
                .authority(AUTHORITY).appendPath(TABLE_PERMISSIONS).appendPath("*")
                .build();
        Log.v(TAG, "Asking " + providerUri + " to delete permissions for " + packageName);
        final int deleted = context.getContentResolver().delete(providerUri, null, new String[] {
                packageName
        });
        Log.d(TAG, "Deleted " + deleted + " entries for package " + packageName);

        // Update UI
        refreshGrantedUriPermissions();
    }

    private void removeUriPermissionsFromUi() {
        // Remove all preferences but the clear button.
        int count = mUri.getPreferenceCount();
        for (int i = count - 1; i >= 0; i--) {
            Preference pref = mUri.getPreference(i);
            if (pref != mClearUri) {
                mUri.removePreference(pref);
            }
        }
    }

    @Override
    protected AlertDialog createDialog(int id, int errorCode) {
        switch (id) {
            case DLG_CLEAR_DATA:
                return new AlertDialog.Builder(getActivity())
                        .setTitle(getActivity().getText(R.string.clear_data_dlg_title))
                        .setMessage(getActivity().getText(R.string.clear_data_dlg_text))
                        .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                // Clear user data here
                                initiateClearUserData();
                            }
                        })
                        .setNegativeButton(R.string.dlg_cancel, null)
                        .create();
            case DLG_CANNOT_CLEAR_DATA:
                return new AlertDialog.Builder(getActivity())
                        .setTitle(getActivity().getText(R.string.clear_user_data_text))
                        .setMessage(getActivity().getText(R.string.clear_failed_dlg_text))
                        .setNeutralButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                mButtonsPref.setButton1Enabled(false);
                                //force to recompute changed value
                                setIntentAndFinish(false, false);
                            }
                        })
                        .create();
        }
        return null;
    }

    @Override
    public void onPackageSizeChanged(String packageName) {
    }

    @Override
    public Loader<AppStorageStats> onCreateLoader(int id, Bundle args) {
        Context context = getContext();
        return new FetchPackageStorageAsyncLoader(
                context, new StorageStatsSource(context), mInfo, UserHandle.of(mUserId));
    }

    @Override
    public void onLoadFinished(Loader<AppStorageStats> loader, AppStorageStats result) {
        mSizeController.setResult(result);
        updateUiWithSize(result);
    }

    @Override
    public void onLoaderReset(Loader<AppStorageStats> loader) {
    }

    private void updateSize() {
        PackageManager packageManager = getPackageManager();
        try {
            mInfo = packageManager.getApplicationInfo(mPackageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Could not find package", e);
        }

        if (mInfo == null) {
            return;
        }

        getLoaderManager().restartLoader(1, Bundle.EMPTY, this);
    }

    @VisibleForTesting
    void updateUiWithSize(AppStorageStats result) {
        if (mCacheCleared) {
            mSizeController.setCacheCleared(true);
        }
        if (mDataCleared) {
            mSizeController.setDataCleared(true);
        }

        mSizeController.updateUi(getContext());

        if (result == null) {
            mButtonsPref.setButton1Enabled(false).setButton2Enabled(false);
        } else {
            long cacheSize = result.getCacheBytes();
            long dataSize = result.getDataBytes() - cacheSize;

            if (dataSize <= 0 || !mCanClearData || mDataCleared) {
                mButtonsPref.setButton1Enabled(false);
            } else {
                mButtonsPref.setButton1Enabled(true)
                        .setButton1OnClickListener(v -> handleClearDataClick());
            }
            if (cacheSize <= 0 || mCacheCleared) {
                mButtonsPref.setButton2Enabled(false);
            } else {
                mButtonsPref.setButton2Enabled(true)
                        .setButton2OnClickListener(v -> handleClearCacheClick());
            }
        }
        if (mAppsControlDisallowedBySystem) {
            mButtonsPref.setButton1Enabled(false).setButton2Enabled(false);
        }
    }

    private final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            if (getView() == null) {
                return;
            }
            switch (msg.what) {
                case MSG_CLEAR_USER_DATA:
                    mDataCleared = true;
                    mCacheCleared = true;
                    processClearMsg(msg);
                    break;
                case MSG_CLEAR_CACHE:
                    mCacheCleared = true;
                    // Refresh size info
                    updateSize();
                    break;
            }
        }
    };

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

    class ClearCacheObserver extends IPackageDataObserver.Stub {
        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
            final Message msg = mHandler.obtainMessage(MSG_CLEAR_CACHE);
            msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
            mHandler.sendMessage(msg);
        }
    }

    class ClearUserDataObserver extends IPackageDataObserver.Stub {
        public void onRemoveCompleted(final String packageName, final boolean succeeded) {
            final Message msg = mHandler.obtainMessage(MSG_CLEAR_USER_DATA);
            msg.arg1 = succeeded ? OP_SUCCESSFUL : OP_FAILED;
            mHandler.sendMessage(msg);
        }
    }
}
