/*
       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.mediacapture;

import android.os.Bundle;
import android.util.SparseArray;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Holds the pending javascript requests for the plugin
 */
public class PendingRequests {
    private static final String LOG_TAG = "PendingCaptureRequests";

    private static final String CURRENT_ID_KEY = "currentReqId";
    private static final String REQUEST_KEY_PREFIX = "request_";

    private int currentReqId = 0;
    private SparseArray<Request> requests = new SparseArray<Request>();

    private Bundle lastSavedState;
    private CallbackContext resumeContext;

    /**
     * Creates a request and adds it to the array of pending requests. Each created request gets a
     * unique result code for use with startActivityForResult() and requestPermission()
     * @param action            The action this request corresponds to (capture image, capture audio, etc.)
     * @param options           The options for this request passed from the javascript
     * @param callbackContext   The CallbackContext to return the result to
     * @return                  The newly created Request object with a unique result code
     * @throws JSONException
     */
    public synchronized Request createRequest(int action, JSONObject options, CallbackContext callbackContext) throws JSONException {
        Request req = new Request(action, options, callbackContext);
        requests.put(req.requestCode, req);
        return req;
    }

    /**
     * Gets the request corresponding to this request code
     * @param requestCode   The request code for the desired request
     * @return              The request corresponding to the given request code or null if such a
     *                      request is not found
     */
    public synchronized Request get(int requestCode) {
        // Check to see if this request was saved
        if (lastSavedState != null && lastSavedState.containsKey(REQUEST_KEY_PREFIX + requestCode)) {
            Request r = new Request(lastSavedState.getBundle(REQUEST_KEY_PREFIX + requestCode), this.resumeContext, requestCode);
            requests.put(requestCode, r);

            // Only one of the saved requests will get restored, because that's all cordova-android
            // supports. Having more than one is an extremely unlikely scenario anyway
            this.lastSavedState = null;
            this.resumeContext = null;

            return r;
        }

        return requests.get(requestCode);
    }

    /**
     * Removes the request from the array of pending requests and sends an error plugin result
     * to the CallbackContext that contains the given error object
     * @param req   The request to be resolved
     * @param error The error to be returned to the CallbackContext
     */
    public synchronized void resolveWithFailure(Request req, JSONObject error) {
        req.callbackContext.error(error);
        requests.remove(req.requestCode);
    }

    /**
     * Removes the request from the array of pending requests and sends a successful plugin result
     * to the CallbackContext that contains the result of the request
     * @param req   The request to be resolved
     */
    public synchronized void resolveWithSuccess(Request req) {
        req.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, req.results));
        requests.remove(req.requestCode);
    }


    /**
     * Each request gets a unique ID that represents its request code when calls are made to
     * Activities and for permission requests
     * @return  A unique request code
     */
    private synchronized int incrementCurrentReqId() {
        return currentReqId ++;
    }

    /**
     * Restore state saved by calling toBundle along with a callbackContext to be used in
     * delivering the results of a pending callback
     *
     * @param lastSavedState    The bundle received from toBundle()
     * @param resumeContext     The callbackContext to return results to
     */
    public synchronized void setLastSavedState(Bundle lastSavedState, CallbackContext resumeContext) {
        this.lastSavedState = lastSavedState;
        this.resumeContext = resumeContext;
        this.currentReqId = lastSavedState.getInt(CURRENT_ID_KEY);
    }

    /**
     * Save the current pending requests to a bundle for saving when the Activity gets destroyed.
     *
     * @return  A Bundle that can be used to restore state using setLastSavedState()
     */
    public synchronized Bundle toBundle() {
        Bundle bundle = new Bundle();
        bundle.putInt(CURRENT_ID_KEY, currentReqId);

        for (int i = 0; i < requests.size(); i++) {
            Request r = requests.valueAt(i);
            int requestCode = requests.keyAt(i);
            bundle.putBundle(REQUEST_KEY_PREFIX + requestCode, r.toBundle());
        }

        if (requests.size() > 1) {
            // This scenario is hopefully very unlikely because there isn't much that can be
            // done about it. Should only occur if an external Activity is launched while
            // there is a pending permission request and the device is on low memory
            LOG.w(LOG_TAG, "More than one media capture request pending on Activity destruction. Some requests will be dropped!");
        }

        return bundle;
    }

    /**
     * Holds the options and CallbackContext for a capture request made to the plugin.
     */
    public class Request {

        // Keys for use in saving requests to a bundle
        private static final String ACTION_KEY = "action";
        private static final String LIMIT_KEY = "limit";
        private static final String DURATION_KEY = "duration";
        private static final String QUALITY_KEY = "quality";
        private static final String RESULTS_KEY = "results";

        // Unique int used to identify this request in any Android Permission or Activity callbacks
        public int requestCode;

        // The action that this request is performing
        public int action;

        // The number of pics/vids/audio clips to take (CAPTURE_IMAGE, CAPTURE_VIDEO, CAPTURE_AUDIO)
        public long limit = 1;

        // Optional max duration of recording in seconds (CAPTURE_VIDEO only)
        public int duration = 0;

        // Quality level for video capture 0 low, 1 high (CAPTURE_VIDEO only)
        public int quality = 1;

        // The array of results to be returned to the javascript callback on success
        public JSONArray results = new JSONArray();

        // The callback context for this plugin request
        private CallbackContext callbackContext;

        private Request(int action, JSONObject options, CallbackContext callbackContext) throws JSONException {
            this.callbackContext = callbackContext;
            this.action = action;

            if (options != null) {
                this.limit = options.optLong("limit", 1);
                this.duration = options.optInt("duration", 0);
                this.quality = options.optInt("quality", 1);
            }

            this.requestCode = incrementCurrentReqId();
        }

        private Request(Bundle bundle, CallbackContext callbackContext, int requestCode) {
            this.callbackContext = callbackContext;
            this.requestCode = requestCode;
            this.action = bundle.getInt(ACTION_KEY);
            this.limit = bundle.getLong(LIMIT_KEY);
            this.duration = bundle.getInt(DURATION_KEY);
            this.quality = bundle.getInt(QUALITY_KEY);

            try {
                this.results = new JSONArray(bundle.getString(RESULTS_KEY));
            } catch(JSONException e) {
                // This should never be caught
                LOG.e(LOG_TAG, "Error parsing results for request from saved bundle", e);
            }
        }

        private Bundle toBundle() {
            Bundle bundle = new Bundle();

            bundle.putInt(ACTION_KEY, this.action);
            bundle.putLong(LIMIT_KEY, this.limit);
            bundle.putInt(DURATION_KEY, this.duration);
            bundle.putInt(QUALITY_KEY, this.quality);
            bundle.putString(RESULTS_KEY, this.results.toString());

            return bundle;
        }
    }
}
