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

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;

import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.UserHandle;
import android.telephony.LocationAccessPolicy;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

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

@RunWith(Parameterized.class)
public class LocationAccessPolicyTest {
    private static class Scenario {
        static class Builder {
            private int mAppSdkLevel;
            private boolean mAppHasFineManifest = false;
            private boolean mAppHasCoarseManifest = false;
            private int mFineAppOp = AppOpsManager.MODE_IGNORED;
            private int mCoarseAppOp = AppOpsManager.MODE_IGNORED;
            private boolean mIsDynamicLocationEnabled;
            private LocationAccessPolicy.LocationPermissionQuery mQuery;
            private LocationAccessPolicy.LocationPermissionResult mExpectedResult;
            private String mName;

            public Builder setAppSdkLevel(int appSdkLevel) {
                mAppSdkLevel = appSdkLevel;
                return this;
            }

            public Builder setAppHasFineManifest(boolean appHasFineManifest) {
                mAppHasFineManifest = appHasFineManifest;
                return this;
            }

            public Builder setAppHasCoarseManifest(
                    boolean appHasCoarseManifest) {
                mAppHasCoarseManifest = appHasCoarseManifest;
                return this;
            }

            public Builder setFineAppOp(int fineAppOp) {
                mFineAppOp = fineAppOp;
                return this;
            }

            public Builder setCoarseAppOp(int coarseAppOp) {
                mCoarseAppOp = coarseAppOp;
                return this;
            }

            public Builder setIsDynamicLocationEnabled(
                    boolean isDynamicLocationEnabled) {
                mIsDynamicLocationEnabled = isDynamicLocationEnabled;
                return this;
            }

            public Builder setQuery(
                    LocationAccessPolicy.LocationPermissionQuery query) {
                mQuery = query;
                return this;
            }

            public Builder setExpectedResult(
                    LocationAccessPolicy.LocationPermissionResult expectedResult) {
                mExpectedResult = expectedResult;
                return this;
            }

            public Builder setName(String name) {
                mName = name;
                return this;
            }

            public Scenario build() {
                return new Scenario(mAppSdkLevel, mAppHasFineManifest, mAppHasCoarseManifest,
                        mFineAppOp, mCoarseAppOp, mIsDynamicLocationEnabled, mQuery,
                        mExpectedResult, mName);
            }
        }
        int appSdkLevel;
        boolean appHasFineManifest;
        boolean appHasCoarseManifest;
        int fineAppOp;
        int coarseAppOp;
        boolean isDynamicLocationEnabled;
        LocationAccessPolicy.LocationPermissionQuery query;
        LocationAccessPolicy.LocationPermissionResult expectedResult;
        String name;

        private Scenario(int appSdkLevel, boolean appHasFineManifest, boolean appHasCoarseManifest,
                int fineAppOp, int coarseAppOp,
                boolean isDynamicLocationEnabled,
                LocationAccessPolicy.LocationPermissionQuery query,
                LocationAccessPolicy.LocationPermissionResult expectedResult,
                String name) {
            this.appSdkLevel = appSdkLevel;
            this.appHasFineManifest = appHasFineManifest;
            this.appHasCoarseManifest = appHasFineManifest || appHasCoarseManifest;
            this.fineAppOp = fineAppOp;
            this.coarseAppOp = coarseAppOp == AppOpsManager.MODE_ALLOWED ? coarseAppOp : fineAppOp;
            this.isDynamicLocationEnabled = isDynamicLocationEnabled;
            this.query = query;
            this.expectedResult = expectedResult;
            this.name = name;
        }

        @Override
        public String toString() {
            return name;
        }
    }

    private static final int TESTING_UID = 10001;
    private static final int TESTING_PID = 8009;

    @Mock Context mContext;
    @Mock AppOpsManager mAppOpsManager;
    @Mock LocationManager mLocationManager;
    @Mock PackageManager mPackageManager;
    Scenario mScenario;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mockContextSystemService(AppOpsManager.class, mAppOpsManager);
        mockContextSystemService(LocationManager.class, mLocationManager);
        mockContextSystemService(PackageManager.class, mPackageManager);
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
    }

    private <T> void mockContextSystemService(Class<T> clazz , T obj) {
        when(mContext.getSystemServiceName(eq(clazz))).thenReturn(clazz.getSimpleName());
        when(mContext.getSystemService(clazz.getSimpleName())).thenReturn(obj);
    }

    public LocationAccessPolicyTest(Scenario scenario) {
        mScenario = scenario;
    }


    @Test
    public void test() {
        setupScenario(mScenario);
        assertEquals(mScenario.expectedResult,
                LocationAccessPolicy.checkLocationPermission(mContext, mScenario.query));
    }

    private void setupScenario(Scenario s) {
        when(mContext.checkPermission(eq(Manifest.permission.ACCESS_FINE_LOCATION),
                anyInt(), anyInt())).thenReturn(s.appHasFineManifest
                ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);

        when(mContext.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION),
                anyInt(), anyInt())).thenReturn(s.appHasCoarseManifest
                ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);

        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_FINE_LOCATION),
                anyInt(), anyString()))
                .thenReturn(s.fineAppOp);
        when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OP_COARSE_LOCATION),
                anyInt(), anyString()))
                .thenReturn(s.coarseAppOp);

        // set this permission to denied by default, and only allow for the proper pid/uid
        // combination
        when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
                anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_DENIED);
        if (s.isDynamicLocationEnabled) {
            when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class))).thenReturn(true);
            when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL),
                    eq(TESTING_PID), eq(TESTING_UID)))
                    .thenReturn(PackageManager.PERMISSION_GRANTED);
        } else {
            when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class)))
                    .thenReturn(false);
        }

        ApplicationInfo fakeAppInfo = new ApplicationInfo();
        fakeAppInfo.targetSdkVersion = s.appSdkLevel;

        try {
            when(mPackageManager.getApplicationInfo(anyString(), anyInt()))
                    .thenReturn(fakeAppInfo);
        } catch (Exception e) {
            // this is a formality
        }
    }

    private static LocationAccessPolicy.LocationPermissionQuery.Builder getDefaultQueryBuilder() {
        return new LocationAccessPolicy.LocationPermissionQuery.Builder()
                .setMethod("test")
                .setCallingPackage("com.android.test")
                .setCallingPid(TESTING_PID)
                .setCallingUid(TESTING_UID);
    }

    @Parameterized.Parameters(name = "{0}")
    public static Collection<Scenario> getScenarios() {
        List<Scenario> scenarios = new ArrayList<>();
        scenarios.add(new Scenario.Builder()
                .setName("System location is off")
                .setAppHasFineManifest(true)
                .setFineAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(false)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.N)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.N).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.DENIED_SOFT)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on latest SDK level has all proper permissions for fine")
                .setAppHasFineManifest(true)
                .setFineAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.N)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.N).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.ALLOWED)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on older SDK level missing permissions for fine but has coarse")
                .setAppHasCoarseManifest(true)
                .setCoarseAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(Build.VERSION_CODES.JELLY_BEAN)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.M)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.JELLY_BEAN).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.ALLOWED)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on latest SDK level missing fine app ops permission")
                .setAppHasFineManifest(true)
                .setFineAppOp(AppOpsManager.MODE_ERRORED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.N)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.N).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.DENIED_HARD)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App has coarse permission but fine permission isn't being enforced yet")
                .setAppHasCoarseManifest(true)
                .setCoarseAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(LocationAccessPolicy.MAX_SDK_FOR_ANY_ENFORCEMENT + 1)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(
                                LocationAccessPolicy.MAX_SDK_FOR_ANY_ENFORCEMENT + 1)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.N).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.ALLOWED)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on latest SDK level has coarse but missing fine when fine is req.")
                .setAppHasCoarseManifest(true)
                .setCoarseAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.P)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.N).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.DENIED_HARD)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on latest SDK level has MODE_IGNORED for app ops on fine")
                .setAppHasCoarseManifest(true)
                .setCoarseAppOp(AppOpsManager.MODE_ALLOWED)
                .setFineAppOp(AppOpsManager.MODE_IGNORED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.P)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.O).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.DENIED_HARD)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App has no permissions but it's sdk level grandfathers it in")
                .setAppSdkLevel(Build.VERSION_CODES.N)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.O).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.ALLOWED)
                .build());

        scenarios.add(new Scenario.Builder()
                .setName("App on latest SDK level has proper permissions for coarse")
                .setAppHasCoarseManifest(true)
                .setCoarseAppOp(AppOpsManager.MODE_ALLOWED)
                .setAppSdkLevel(Build.VERSION_CODES.P)
                .setIsDynamicLocationEnabled(true)
                .setQuery(getDefaultQueryBuilder()
                        .setMinSdkVersionForCoarse(Build.VERSION_CODES.P).build())
                .setExpectedResult(LocationAccessPolicy.LocationPermissionResult.ALLOWED)
                .build());
        return scenarios;
    }
}
