/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you 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 org.apache.cordova;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.LOG;

import android.content.pm.PackageManager;

/**
 * This class provides reflective methods for permission requesting and checking so that plugins
 * written for cordova-android 5.0.0+ can still compile with earlier cordova-android versions.
 */
public class PermissionHelper {
    private static final String LOG_TAG = "CordovaPermissionHelper";

    /**
     * Requests a "dangerous" permission for the application at runtime. This is a helper method
     * alternative to cordovaInterface.requestPermission() that does not require the project to be
     * built with cordova-android 5.0.0+
     *
     * @param plugin        The plugin the permission is being requested for
     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()
     *                      along with the result of the permission request
     * @param permission    The permission to be requested
     */
    public static void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
        PermissionHelper.requestPermissions(plugin, requestCode, new String[] {permission});
    }

    /**
     * Requests "dangerous" permissions for the application at runtime. This is a helper method
     * alternative to cordovaInterface.requestPermissions() that does not require the project to be
     * built with cordova-android 5.0.0+
     *
     * @param plugin        The plugin the permissions are being requested for
     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()
     *                      along with the result of the permissions request
     * @param permissions   The permissions to be requested
     */
    public static void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
        try {
            Method requestPermission = CordovaInterface.class.getDeclaredMethod(
                    "requestPermissions", CordovaPlugin.class, int.class, String[].class);

            // If there is no exception, then this is cordova-android 5.0.0+
            requestPermission.invoke(plugin.cordova, plugin, requestCode, permissions);
        } catch (NoSuchMethodException noSuchMethodException) {
            // cordova-android version is less than 5.0.0, so permission is implicitly granted
            LOG.d(LOG_TAG, "No need to request permissions " + Arrays.toString(permissions));

            // Notify the plugin that all were granted by using more reflection
            deliverPermissionResult(plugin, requestCode, permissions);
        } catch (IllegalAccessException illegalAccessException) {
            // Should never be caught; this is a public method
            LOG.e(LOG_TAG, "IllegalAccessException when requesting permissions " + Arrays.toString(permissions), illegalAccessException);
        } catch(InvocationTargetException invocationTargetException) {
            // This method does not throw any exceptions, so this should never be caught
            LOG.e(LOG_TAG, "invocationTargetException when requesting permissions " + Arrays.toString(permissions), invocationTargetException);
        }
    }

    /**
     * Checks at runtime to see if the application has been granted a permission. This is a helper
     * method alternative to cordovaInterface.hasPermission() that does not require the project to
     * be built with cordova-android 5.0.0+
     *
     * @param plugin        The plugin the permission is being checked against
     * @param permission    The permission to be checked
     *
     * @return              True if the permission has already been granted and false otherwise
     */
    public static boolean hasPermission(CordovaPlugin plugin, String permission) {
        try {
            Method hasPermission = CordovaInterface.class.getDeclaredMethod("hasPermission", String.class);

            // If there is no exception, then this is cordova-android 5.0.0+
            return (Boolean) hasPermission.invoke(plugin.cordova, permission);
        } catch (NoSuchMethodException noSuchMethodException) {
            // cordova-android version is less than 5.0.0, so permission is implicitly granted
            LOG.d(LOG_TAG, "No need to check for permission " + permission);
            return true;
        } catch (IllegalAccessException illegalAccessException) {
            // Should never be caught; this is a public method
            LOG.e(LOG_TAG, "IllegalAccessException when checking permission " + permission, illegalAccessException);
        } catch(InvocationTargetException invocationTargetException) {
            // This method does not throw any exceptions, so this should never be caught
            LOG.e(LOG_TAG, "invocationTargetException when checking permission " + permission, invocationTargetException);
        }
        return false;
    }

    private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {
        // Generate the request results
        int[] requestResults = new int[permissions.length];
        Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);

        try {
            Method onRequestPermissionResult = CordovaPlugin.class.getDeclaredMethod(
                    "onRequestPermissionResult", int.class, String[].class, int[].class);

            onRequestPermissionResult.invoke(plugin, requestCode, permissions, requestResults);
        } catch (NoSuchMethodException noSuchMethodException) {
            // Should never be caught since the plugin must be written for cordova-android 5.0.0+ if it
            // made it to this point
            LOG.e(LOG_TAG, "NoSuchMethodException when delivering permissions results", noSuchMethodException);
        } catch (IllegalAccessException illegalAccessException) {
            // Should never be caught; this is a public method
            LOG.e(LOG_TAG, "IllegalAccessException when delivering permissions results", illegalAccessException);
        } catch(InvocationTargetException invocationTargetException) {
            // This method may throw a JSONException. We are just duplicating cordova-android's
            // exception handling behavior here; all it does is log the exception in CordovaActivity,
            // print the stacktrace, and ignore it
            LOG.e(LOG_TAG, "InvocationTargetException when delivering permissions results", invocationTargetException);
        }
    }
}
