/*
 * Copyright (C) 2018 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.permissioncontroller.permission.ui.legacy;

import static android.content.Intent.ACTION_MANAGE_APP_PERMISSION;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;

import static com.android.permissioncontroller.Constants.EXTRA_SESSION_ID;
import static com.android.permissioncontroller.Constants.INVALID_SESSION_ID;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.Log;
import android.view.MenuItem;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.android.permissioncontroller.DeviceUtils;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.ui.LocationProviderInterceptDialog;
import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity;
import com.android.permissioncontroller.permission.ui.auto.AutoAppPermissionFragment;
import com.android.permissioncontroller.permission.ui.television.AppPermissionFragment;
import com.android.permissioncontroller.permission.utils.LocationUtils;
import com.android.permissioncontroller.permission.utils.PermissionMapping;
import com.android.permissioncontroller.permission.utils.Utils;

import java.util.List;
import java.util.Random;

/**
 * Manage a single permission of a single app.
 *
 * @deprecated This class is deprecated for handheld UI, and will throw an error if used for
 * handheld (read: non auto, TV, or wear) UIs. Instead, users should create an intent with the
 * ACTION_MANAGE_APP_PERMISSION action, which will intent into the ManagePermissionsActivity.
 *
 * @see ManagePermissionsActivity
 */
@Deprecated
public final class AppPermissionActivity extends FragmentActivity {
    private static final String LOG_TAG = AppPermissionActivity.class.getSimpleName();

    public static final String EXTRA_CALLER_NAME =
            "com.android.permissioncontroller.extra.CALLER_NAME";

    // The permission group which was interacted with
    public static final String EXTRA_RESULT_PERMISSION_INTERACTED = "com.android"
            + ".permissioncontroller.extra.RESULT_PERMISSION_INTERACTED";
    /**
     * The result of the permission in terms of {@link GrantPermissionsViewHandler.Result}
     */
    public static final String EXTRA_RESULT_PERMISSION_RESULT = "com.android"
            + ".permissioncontroller.extra.PERMISSION_RESULT";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        if (!DeviceUtils.isAuto(this) && !DeviceUtils.isWear(this)
                && !DeviceUtils.isTelevision(this)) {
            throw new IllegalStateException("Do not use AppPermissionActivity for handheld ui. "
                    + "Create intent with ACTION_MANAGE_APP_PERMISSION instead.");
        }
        if (DeviceUtils.isAuto(this)) {
            // Automotive relies on a different theme. Apply before calling super so that
            // fragments are restored properly on configuration changes.
            setTheme(R.style.CarSettings);
        }
        super.onCreate(savedInstanceState);

        getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);

        String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME);
        if (packageName == null) {
            Log.e(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME");
            finish();
            return;
        }

        String permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME);
        String groupName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME);
        if (permissionName == null && groupName == null) {
            Log.e(LOG_TAG, "Missing argument EXTRA_PERMISSION_NAME or "
                    + "EXTRA_PERMISSION_GROUP_NAME, at least one must be present.");
            finish();
            return;
        }
        if (groupName == null) {
            groupName = PermissionMapping.getGroupOfPlatformPermission(permissionName);
            PermissionInfo permission;
            try {
                permission = getPackageManager().getPermissionInfo(permissionName, 0);
                if (!permission.packageName.equals(Utils.OS_PKG)) {
                    List<PermissionGroupInfo> groupInfos =
                            getPackageManager().getAllPermissionGroups(0);
                    for (PermissionGroupInfo groupInfo : groupInfos) {
                        if (groupInfo.name.equals(permission.group)) {
                            groupName = permission.group;
                        }
                    }

                }
            } catch (PackageManager.NameNotFoundException e) {
                groupName = null;
            }
        }

        UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER);
        if (userHandle == null) {
            Log.e(LOG_TAG, "Missing mandatory argument EXTRA_USER");
            finish();
            return;
        }

        if (LocationUtils.isLocationGroupAndProvider(this, groupName,
                packageName)) {
            Intent intent = new Intent(this, LocationProviderInterceptDialog.class);
            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
            startActivityAsUser(intent, userHandle);
            finish();
            return;
        }

        if (LocationUtils.isLocationGroupAndControllerExtraPackage(
                this, groupName, packageName)) {
            // Redirect to location controller extra package settings.
            LocationUtils.startLocationControllerExtraPackageSettings(this, userHandle);
            finish();
            return;
        }

        if (DeviceUtils.isAuto(this)) {
            Fragment androidXFragment;

            long sessionId = getIntent().getLongExtra(EXTRA_SESSION_ID, INVALID_SESSION_ID);
            while (sessionId == INVALID_SESSION_ID) {
                sessionId = new Random().nextLong();
            }

            androidXFragment = AutoAppPermissionFragment.newInstance(packageName, permissionName,
                    groupName, userHandle, sessionId);

            getSupportFragmentManager().beginTransaction().replace(android.R.id.content,
                    androidXFragment).commit();
        } else if (DeviceUtils.isTelevision(this)) {
            Fragment androidXFragment = new AppPermissionFragment();
            androidXFragment.setArguments(
                    AppPermissionFragment.createArgs(
                            packageName, permissionName, groupName, userHandle, null, 0, null));
            getSupportFragmentManager().beginTransaction()
                    .replace(android.R.id.content, androidXFragment)
                    .commit();
        } else {
            startActivity(new Intent(getIntent()).setAction(ACTION_MANAGE_APP_PERMISSION));
            finish();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // in automotive mode, there's no system wide back button, so need to add that
        if (DeviceUtils.isAuto(this)) {
            switch (item.getItemId()) {
                case android.R.id.home:
                    onBackPressed();
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
        }
        return super.onOptionsItemSelected(item);
    }
}
