/*
* 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.packageinstaller.permission.ui.wear;

import android.Manifest;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.wearable.view.WearableListView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.android.packageinstaller.R;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.ui.wear.settings.PermissionsSettingsAdapter;
import com.android.packageinstaller.permission.ui.wear.settings.SettingsAdapter;
import com.android.packageinstaller.permission.utils.LocationUtils;
import com.android.packageinstaller.permission.utils.SafetyNetLogger;
import com.android.packageinstaller.permission.utils.Utils;

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

public final class AppPermissionsFragmentWear extends TitledSettingsFragment {

    private static final String LOG_TAG = "ManagePermsFragment";

    private static final int WARNING_CONFIRMATION_REQUEST = 252;
    private List<AppPermissionGroup> mToggledGroups;
    private AppPermissions mAppPermissions;
    private PermissionsSettingsAdapter mAdapter;

    private boolean mHasConfirmedRevoke;

    public static AppPermissionsFragmentWear newInstance(String packageName) {
        return setPackageName(new AppPermissionsFragmentWear(), packageName);
    }

    private static <T extends Fragment> T setPackageName(T fragment, String packageName) {
        Bundle arguments = new Bundle();
        arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
        fragment.setArguments(arguments);
        return fragment;
    }

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

        String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME);
        Activity activity = getActivity();
        PackageManager pm = activity.getPackageManager();
        PackageInfo packageInfo;

        try {
            packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
        } catch (PackageManager.NameNotFoundException e) {
            Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e);
            packageInfo = null;
        }

        if (packageInfo == null) {
            Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show();
            activity.finish();
            return;
        }

        mAppPermissions = new AppPermissions(activity, packageInfo, null, true, new Runnable() {
            @Override
            public void run() {
                getActivity().finish();
            }
        });

        mAdapter = new PermissionsSettingsAdapter(getContext());

        initializePermissionGroupList();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.settings, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        mAppPermissions.refresh();

        // Also refresh the UI
        final int count = mAdapter.getItemCount();
        for (int i = 0; i < count; ++i) {
            updatePermissionGroupSetting(i);
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (mAppPermissions != null) {
            initializeLayout(mAdapter);
            mHeader.setText(R.string.app_permissions);
            mDetails.setText(R.string.no_permissions);
            if (mAdapter.getItemCount() == 0) {
                mDetails.setVisibility(View.VISIBLE);
                mWheel.setVisibility(View.GONE);
            } else {
                mDetails.setVisibility(View.GONE);
                mWheel.setVisibility(View.VISIBLE);
            }
        }
    }

    private void initializePermissionGroupList() {
        final String packageName = mAppPermissions.getPackageInfo().packageName;
        List<AppPermissionGroup> groups = mAppPermissions.getPermissionGroups();
        List<SettingsAdapter.Setting<AppPermissionGroup>> nonSystemGroups = new ArrayList<>();

        final int count = groups.size();
        for (int i = 0; i < count; ++i) {
            final AppPermissionGroup group = groups.get(i);
            if (!Utils.shouldShowPermission(group, packageName)) {
                continue;
            }

            boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG);

            SettingsAdapter.Setting<AppPermissionGroup> setting =
                    new SettingsAdapter.Setting<AppPermissionGroup>(
                            group.getLabel(),
                            getPermissionGroupIcon(group),
                            i);
            setting.data = group;

            // The UI shows System settings first, then non-system settings
            if (isPlatform) {
                mAdapter.addSetting(setting);
            } else {
                nonSystemGroups.add(setting);
            }
        }

        // Now add the non-system settings to the end of the list
        final int nonSystemCount = nonSystemGroups.size();
        for (int i = 0; i < nonSystemCount; ++i) {
            final SettingsAdapter.Setting<AppPermissionGroup> setting = nonSystemGroups.get(i);
            mAdapter.addSetting(setting);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        logAndClearToggledGroups();
    }

    @Override
    public void onClick(WearableListView.ViewHolder view) {
        final int index = view.getPosition();
        SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
        final AppPermissionGroup group = setting.data;

        if (group == null) {
            Log.e(LOG_TAG, "Error: AppPermissionGroup is null");
            return;
        }

        // The way WearableListView is designed, there is no way to avoid this click handler
        // Since the policy is fixed, ignore the click as the user is not able to change the state
        // of this permission group
        if (group.isPolicyFixed()) {
            return;
        }

        addToggledGroup(group);

        if (LocationUtils.isLocationGroupAndProvider(group.getName(), group.getApp().packageName)) {
            LocationUtils.showLocationDialog(getContext(), mAppPermissions.getAppLabel());
            return;
        }

        if (!group.areRuntimePermissionsGranted()) {
            group.grantRuntimePermissions(false);
        } else {
            final boolean grantedByDefault = group.hasGrantedByDefaultPermission();
            if (grantedByDefault || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) {
                Intent intent = new Intent(getActivity(), WarningConfirmationActivity.class);
                intent.putExtra(WarningConfirmationActivity.EXTRA_WARNING_MESSAGE,
                        getString(grantedByDefault ?
                                R.string.system_warning : R.string.old_sdk_deny_warning));
                intent.putExtra(WarningConfirmationActivity.EXTRA_INDEX, index);
                startActivityForResult(intent, WARNING_CONFIRMATION_REQUEST);
            } else {
                group.revokeRuntimePermissions(false);
            }
        }

        updatePermissionGroupSetting(index);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == WARNING_CONFIRMATION_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                int index = data.getIntExtra(WarningConfirmationActivity.EXTRA_INDEX, -1);
                if (index == -1) {
                    Log.e(LOG_TAG, "Warning confirmation request came back with no index.");
                    return;
                }

                SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
                final AppPermissionGroup group = setting.data;
                group.revokeRuntimePermissions(false);
                if (!group.hasGrantedByDefaultPermission()) {
                    mHasConfirmedRevoke = true;
                }

                updatePermissionGroupSetting(index);
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private void updatePermissionGroupSetting(int index) {
        SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index);
        AppPermissionGroup group = setting.data;
        mAdapter.updateSetting(
                index,
                group.getLabel(),
                getPermissionGroupIcon(group),
                group);
    }

    private void addToggledGroup(AppPermissionGroup group) {
        if (mToggledGroups == null) {
            mToggledGroups = new ArrayList<>();
        }
        // Double toggle is back to initial state.
        if (mToggledGroups.contains(group)) {
            mToggledGroups.remove(group);
        } else {
            mToggledGroups.add(group);
        }
    }

    private void logAndClearToggledGroups() {
        if (mToggledGroups != null) {
            String packageName = mAppPermissions.getPackageInfo().packageName;
            SafetyNetLogger.logPermissionsToggled(packageName, mToggledGroups);
            mToggledGroups = null;
        }
    }

    private int getPermissionGroupIcon(AppPermissionGroup group) {
        String groupName = group.getName();
        boolean isEnabled = group.areRuntimePermissionsGranted();
        int resId;

        switch (groupName) {
            case Manifest.permission_group.CALENDAR:
                resId = isEnabled ? R.drawable.ic_permission_calendar
                        : R.drawable.ic_permission_calendardisable;
                break;
            case Manifest.permission_group.CAMERA:
                resId = isEnabled ? R.drawable.ic_permission_camera
                        : R.drawable.ic_permission_cameradisable;
                break;
            case Manifest.permission_group.CONTACTS:
                resId = isEnabled ? R.drawable.ic_permission_contact
                        : R.drawable.ic_permission_contactdisable;
                break;
            case Manifest.permission_group.LOCATION:
                resId = isEnabled ? R.drawable.ic_permission_location
                        : R.drawable.ic_permission_locationdisable;
                break;
            case Manifest.permission_group.MICROPHONE:
                resId = isEnabled ? R.drawable.ic_permission_mic
                        : R.drawable.ic_permission_micdisable;
                break;
            case Manifest.permission_group.PHONE:
                resId = isEnabled ? R.drawable.ic_permission_call
                        : R.drawable.ic_permission_calldisable;
                break;
            case Manifest.permission_group.SENSORS:
                resId = isEnabled ? R.drawable.ic_permission_sensor
                        : R.drawable.ic_permission_sensordisable;
                break;
            case Manifest.permission_group.SMS:
                resId = isEnabled ? R.drawable.ic_permission_sms
                        : R.drawable.ic_permission_smsdisable;
                break;
            case Manifest.permission_group.STORAGE:
                resId = isEnabled ? R.drawable.ic_permission_storage
                        : R.drawable.ic_permission_storagedisable;
                break;
            default:
                resId = isEnabled ? R.drawable.ic_permission_shield
                        : R.drawable.ic_permission_shielddisable;
        }

        return resId;
    }
}
