/*
 * 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 android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppGlobals;
import android.app.LoaderManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.Loader;
import android.content.UriPermission;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
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.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.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;

import static android.content.pm.ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;

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
    private Preference mCacheSize;
    private Button mClearDataButton;
    private Button mClearCacheButton;

    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;

    private 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();

        mClearDataButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
                .findViewById(R.id.left_button);

        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
        mCacheSize = findPreference(KEY_CACHE_SIZE);
        mClearCacheButton = (Button) ((LayoutPreference) findPreference(KEY_HEADER_BUTTONS))
                .findViewById(R.id.right_button);
        mClearCacheButton.setText(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);
    }

    @Override
    public void onClick(View v) {
        if (v == mClearCacheButton) {
            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);
        } else if (v == mClearDataButton) {
            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);
            }
        } else 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) {
            mClearDataButton.setText(R.string.clear_user_data_text);
            mClearDataButton.setEnabled(false);
            mCanClearData = false;
        } else {
            if (appHasSpaceManagementUI) {
                mClearDataButton.setText(R.string.manage_space_text);
            } else {
                mClearDataButton.setText(R.string.clear_user_data_text);
            }
            mClearDataButton.setOnClickListener(this);
        }

        if (mAppsControlDisallowedBySystem) {
            mClearDataButton.setEnabled(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);
        mClearDataButton.setEnabled(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, "Couldnt clear application user data for package:"+packageName);
            showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
        } else {
            mClearDataButton.setText(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;
        mClearDataButton.setText(R.string.clear_user_data_text);
        if (result == OP_SUCCESSFUL) {
            Log.i(TAG, "Cleared user data for package : "+packageName);
            updateSize();
        } else {
            mClearDataButton.setEnabled(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<UriPermission> 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 (UriPermission perm : perms) {
            String authority = perm.getUri().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() {
        // Synchronously revoke the permissions.
        final ActivityManager am = (ActivityManager) getActivity().getSystemService(
                Context.ACTIVITY_SERVICE);
        am.clearGrantedUriPermissions(mAppEntry.info.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_failed_dlg_title))
                        .setMessage(getActivity().getText(R.string.clear_failed_dlg_text))
                        .setNeutralButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                mClearDataButton.setEnabled(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);
    }

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

        mSizeController.updateUi(getContext());

        if (result == null) {
            mClearDataButton.setEnabled(false);
            mClearCacheButton.setEnabled(false);
        } else {
            long codeSize = result.getCodeBytes();
            long cacheSize = result.getCacheBytes();
            long dataSize = result.getDataBytes() - cacheSize;

            if (dataSize <= 0 || !mCanClearData || mDataCleared) {
                mClearDataButton.setEnabled(false);
            } else {
                mClearDataButton.setEnabled(true);
                mClearDataButton.setOnClickListener(this);
            }
            if (cacheSize <= 0 || mCacheCleared) {
                mClearCacheButton.setEnabled(false);
            } else {
                mClearCacheButton.setEnabled(true);
                mClearCacheButton.setOnClickListener(this);
            }
        }
        if (mAppsControlDisallowedBySystem) {
            mClearCacheButton.setEnabled(false);
            mClearDataButton.setEnabled(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);
        }
    }
}
