<%
/*
 * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. 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.
 */

var log = new Log("api/invoker-api.jag");

var uri = request.getRequestURI();
var uriMatcher = new URIMatcher(String(uri));

var constants = require("/app/modules/constants.js");
var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
var serviceInvokers = require("/app/modules/oauth/token-protected-service-invokers.js")["invokers"];

if (uriMatcher.match("/{context}/api/invoker/execute/")) {
    //NOTE: We are only interested in Content-Type headers. Appending all request headers to the back-end call
    // will cause unforeseen security issues.
    var contentType = request.getHeader(constants.CONTENT_TYPE_IDENTIFIER);
    var acceptType = request.getHeader(constants.ACCEPT_IDENTIFIER);
    var requestHeaders = [];
    requestHeaders.push({"name": constants.CONTENT_TYPE_IDENTIFIER, "value" : contentType});
    requestHeaders.push({"name": constants.ACCEPT_IDENTIFIER, "value" : acceptType});

    var restAPIRequestDetails = request.getContent();

    var requestMethod = restAPIRequestDetails["requestMethod"];
    var requestURL = restAPIRequestDetails["requestURL"];
    var requestPayload = restAPIRequestDetails["requestPayload"];

    if (!requestMethod) {
        requestMethod = parse(restAPIRequestDetails)["requestMethod"];
    }

    if (!requestURL) {
        requestURL = parse(restAPIRequestDetails)["requestURL"];
    }

    if (!requestPayload) {
        requestPayload = parse(restAPIRequestDetails)["requestPayload"];
    }

    var restAPIEndpoint = devicemgtProps["httpsURL"] + requestURL;

    try {
        switch (requestMethod) {
            case constants["HTTP_GET"]:
                serviceInvokers.XMLHttp.get(
                    restAPIEndpoint,
                    function (restAPIResponse) {
                        response["status"] = restAPIResponse["status"];
                        if (restAPIResponse["responseText"]) {
                            response["content"] = restAPIResponse["responseText"];
                        }
                    },
                    requestHeaders
                );
                break;
            case constants["HTTP_POST"]:
                serviceInvokers.XMLHttp.post(
                    restAPIEndpoint,
                    requestPayload,
                    function (restAPIResponse) {
                        response["status"] = restAPIResponse["status"];
                        if (restAPIResponse["responseText"]) {
                            response["content"] = restAPIResponse["responseText"];
                        }
                    },
                    requestHeaders
                );
                break;
            case constants["HTTP_PUT"]:
                serviceInvokers.XMLHttp.put(
                    restAPIEndpoint,
                    requestPayload,
                    function (restAPIResponse) {
                        response["status"] = restAPIResponse["status"];
                        if (restAPIResponse["responseText"]) {
                            response["content"] = restAPIResponse["responseText"];
                        }
                    },
                    requestHeaders
                );
                break;
            case constants["HTTP_DELETE"]:
                serviceInvokers.XMLHttp.delete(
                    restAPIEndpoint,
                    function (restAPIResponse) {
                        response["status"] = restAPIResponse["status"];
                        if (restAPIResponse["responseText"]) {
                            response["content"] = restAPIResponse["responseText"];
                        }
                    },
                    requestHeaders
                );
                break;
        }
    } catch (e) {
        //Since this is an API we'll log the error message.
        log.error(e.message); // JavaScript error message
        log.error(e.stack); // Executed JavaScript file stack
        throw new Error("Exception occurred while trying to access " +
                        "backend REST API services from Jaggery API invoker layer", e);
    }
}
%>
