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

var dbg = require('../utils/debug');
var DEBUG = new dbg();

const OW_ENV_PREFIX = "__OW_";
const CONTENT_TYPE = "Content-Type";

/**
 * Determine if runtime is a "stem" cell, i.e., can be initialized with request init. data
 * @param env
 * @returns {boolean}
 */
function isStemCell(env) {
    let actionCode = env.__OW_ACTION_CODE;
    // It is a stem cell if valid code is "built into" the runtime's process environment.
    return (typeof actionCode === 'undefined' || actionCode.length === 0);
}

/**
 * Determine if the request (body) contains valid activation data.
 * @param req
 * @returns {boolean}
 */
function hasActivationData(req) {
    // it is a valid activation if the body contains an activation and value keys with data.
    if (typeof req.body !== "undefined" &&
        typeof req.body.activation !== "undefined" &&
        typeof req.body.value !== "undefined") {
        return true;
    }
    return false;
}

/**
 * Determine if the request (body) contains valid init data.
 * @param req
 * @returns {boolean}
 */
function hasInitData(req) {
    // it is a valid init. if the body contains an init key with data.
    if (typeof req.body !== "undefined" &&
        typeof req.body.init !== "undefined") {
        return true;
    }
    return false;
}


/**
 * Remove all INIT data from the value data that will be passed to the user function.
 * @param body
 */
function removeInitData(body) {

    DEBUG.dumpObject(body,"body");
    if (typeof body !== "undefined" &&
        typeof body.value !== "undefined") {
        delete body.value.code;
        delete body.value.main;
        delete body.value.binary;
        delete body.value.raw;
    }
}

/**
 * Pre-process the incoming
 */
function preProcessInitData(env, initdata, valuedata, activationdata) {
    DEBUG.functionStart();
    try {
        // Set defaults to use INIT data not provided on the request
        // Look first to the process (i.e., Container's) environment variables.
        var main = (typeof env.__OW_ACTION_MAIN === 'undefined') ? "main" : env.__OW_ACTION_MAIN;
        // TODO: Throw error if CODE is NOT defined!
        var code = (typeof env.__OW_ACTION_CODE === 'undefined') ? "" : env.__OW_ACTION_CODE;
        var binary = (typeof env.__OW_ACTION_BINARY === 'undefined') ? false : env.__OW_ACTION_BINARY.toLowerCase() === "true";
        // TODO: default to empty?
        var actionName = (typeof env.__OW_ACTION_NAME === 'undefined') ? "" : env.__OW_ACTION_NAME;
        var raw = (typeof env.__OW_ACTION_RAW === 'undefined') ? false : env.__OW_ACTION_RAW.toLowerCase() === "true";

        DEBUG.dumpObject(actionName, "Action name");
        DEBUG.dumpObject(main, "Action main");
        DEBUG.dumpObject(code, "Action code");
        DEBUG.dumpObject(binary, "Action binary");
        DEBUG.dumpObject(raw, "Action Raw");

        // Look for init data within the request (i.e., "stem cell" runtime, where code is injected by request)
        if (typeof(initdata) !== "undefined") {
            if (initdata.name && typeof initdata.name === 'string') {
                actionName = initdata.name;
            }
            if (initdata.main && typeof initdata.main === 'string') {
                main = initdata.main;
            }
            if (initdata.code && typeof initdata.code === 'string') {
                code = initdata.code;
            }
            if (initdata.binary) {
                if (typeof initdata.binary === 'boolean') {
                    binary = initdata.binary;
                } else {
                    throw ("Invalid Init. data; expected boolean for key 'binary'.");
                }
            }
            if (initdata.raw ) {
                if (typeof initdata.raw === 'boolean') {
                    raw = initdata.raw;
                } else {
                    throw ("Invalid Init. data; expected boolean for key 'raw'.");
                }
            }
        }

        // Move the init data to the request body under the "value" key.
        // This will allow us to reuse the "openwhisk" /init route handler function
        valuedata.main = main;
        valuedata.code = code;
        valuedata.binary = binary;
        valuedata.raw = raw;

        // Action name is a special case, as we have a key collision on "name" between init. data and request
        // param. data (as they both appear within "body.value") so we must save it to its final location
        // as the default Action name as part of the activation data
        // NOTE: if action name is not present in the action data, we will set it regardless even if an empty string
        if( typeof(activationdata) !== "undefined" ) {
            if ( typeof(activationdata.action_name) === "undefined" ||
                (typeof(activationdata.action_name) === "string" && activationdata.action_name.length == 0 )){
                activationdata.action_name = actionName;
            }
        }
        DEBUG.dumpObject(valuedata.main, "valuedata.main");
        DEBUG.dumpObject(valuedata.code , "valuedata.code");
        DEBUG.dumpObject(valuedata.binary, "valuedata.binary");
        DEBUG.dumpObject(valuedata.raw, "valuedata.raw");

    } catch(e){
        console.error(e);
        DEBUG.functionEndError(e.message);
        throw("Unable to initialize the runtime: " + e.message);
    }
    DEBUG.functionEnd();
}

/**
 * Pre-process the incoming http request data, moving it to where the
 * route handlers expect it to be for an openwhisk runtime.
 */
function preProcessActivationData(env, activationdata) {
    DEBUG.functionStart();
    try {
        // Note: we move the values here so that the "run()" handler does not have
        // to move them again.
        Object.keys(activationdata).forEach(
            function (k) {
                if (typeof activationdata[k] === 'string') {
                    var envVariable = OW_ENV_PREFIX + k.toUpperCase();
                    process.env[envVariable] = activationdata[k];
                    DEBUG.dumpObject(process.env[envVariable], envVariable, "preProcessActivationData");
                }
            }
        );
    } catch(e){
        console.error(e);
        DEBUG.functionEndError(e.message);
        throw("Unable to initialize the runtime: " + e.message);
    }
    DEBUG.functionEnd();
}

/**
 * Pre-process HTTP request information and make it available as parameter data to the action function
 * by moving it to where the route handlers expect it to be (i.e., in the JSON value data map).
 *
 * See: https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md#http-context
 *
 * HTTP Context
 * ============
 * All web actions, when invoked, receives additional HTTP request details as parameters to the action
 * input argument. These include:
 *
 * __ow_method (type: string): the HTTP method of the request.
 * __ow_headers (type: map string to string): the request headers.
 * __ow_path (type: string): the unmatched path of the request (matching stops after consuming the action extension).
 * __ow_user (type: string): the namespace identifying the OpenWhisk authenticated subject.
 * __ow_body (type: string): the request body entity, as a base64 encoded string when content is
 *      binary or JSON object/array, or plain string otherwise.
 * __ow_query (type: string): the query parameters from the request as an unparsed string.
 *
 * TODO:
 * A request may not override any of the named __ow_ parameters above; doing so will result in a
 * failed request with status equal to 400 Bad Request.
 */
function preProcessHTTPContext(req, valueData) {
    DEBUG.functionStart();
    try {
        if (valueData.raw) {
            // __ow_body is a base64 encoded string when content is binary or JSON object/array,
            // or plain string otherwise.
            if (typeof req.body.value === "string" && req.body.value !== undefined) {
                valueData.__ow_body = req.body.value;
            } else {
                // make value data available as __ow_body
                const tmpBody = Object.assign({}, req.body.value);
                // delete main, binary, raw, and code from the body before sending it as an action argument
                delete tmpBody.main;
                delete tmpBody.code;
                delete tmpBody.binary;
                delete tmpBody.raw;
                var bodyStr = JSON.stringify(tmpBody);
                // note: we produce an empty map if there are no query parms/
                valueData.__ow_body = Buffer.from(bodyStr).toString("base64");;
            }
            valueData.__ow_query = req.query;
        }

        var namespace = "";
        if (process.env[OW_ENV_PREFIX + "NAMESPACE"] !== undefined) {
            namespace = process.env[OW_ENV_PREFIX + "NAMESPACE"];
        }
        valueData.__ow_user = namespace;
        valueData.__ow_method = req.method;
        valueData.__ow_headers = req.headers;
        valueData.__ow_path = "";
    } catch (e) {
        console.error(e);
        DEBUG.functionEndError(e.message);
        throw ("Unable to initialize the runtime: " + e.message)
    }
    DEBUG.functionEnd()
}


/**
 * Pre-process the incoming http request data, moving it to where the
 * route handlers expect it to be for an openwhisk runtime.
 */
function preProcessRequest(req){
    DEBUG.functionStart();
    try {
        // Get or create valid references to the various data we might encounter
        // in a request such as Init., Activation and function parameter data.
        let body = req.body || {};
        let valueData = body.value || {};
        let initData = body.init || {};
        let activationData = body.activation || {};
        let env = process.env || {};

        // Fix up pointers in case we had to allocate new maps
        req.body = body;
        req.body.value = valueData;
        req.body.init = initData;
        req.body.activation = activationData;

        // process initialization (i.e., "init") data
        preProcessInitData(env, initData, valueData, activationData);

        // process HTTP request header and body to make it available to function as parameter data
        preProcessHTTPContext(req, valueData);

        // process per-activation (i.e, "run") data
        preProcessActivationData(env, activationData);

    } catch(e){
        console.error(e);
        DEBUG.functionEndError(e.message);
        // TODO: test this error is handled properly and results in an HTTP error response
        throw("Unable to initialize the runtime: " + e.message);
    }
    DEBUG.functionEnd();
}

function postProcessResponse(req, result, res) {
    DEBUG.functionStart();

    var content_types = {
        json: 'application/json',
        html: 'text/html',
        png: 'image/png',
        svg: 'image/svg+xml',
    };

    // After getting the result back from an action, update the HTTP headers,
    // status code, and body based on its result if it includes one or more of the
    // following as top level JSON properties: headers, statusCode, body
    let statusCode = result.code;
    let headers = {};
    let body = result.response;
    let contentTypeInHeader = false;

    // statusCode: default is 200 OK if body is not empty otherwise 204 No Content
    if (result.response.statusCode !== undefined) {
        statusCode = result.response.statusCode;
        delete body['statusCode'];
    }

    // the default content-type for an HTTP response is application/json
    // this default are overwritten with the action specified headers
    if (result.response.headers !== undefined) {
        headers = result.response.headers;
        delete body['headers'];
    }

    // addressing content-type v/s Content-Type
    // marking 'Content-Type' as standard inside header
    if (headers.hasOwnProperty(CONTENT_TYPE.toLowerCase())) {
        headers[CONTENT_TYPE] = headers[CONTENT_TYPE.toLowerCase()];
        delete headers[CONTENT_TYPE.toLowerCase()];
    }

    //  If a content-type header is not declared in the action result’s headers,
    //  the body is interpreted as application/json for non-string values,
    //  and text/html otherwise.
    if (!headers.hasOwnProperty(CONTENT_TYPE)) {
        if (result.response.body !== undefined && typeof result.response.body == "string") {
            headers[CONTENT_TYPE] = content_types.html;
        } else {
            headers[CONTENT_TYPE] = content_types.json;
        }
    } else {
        contentTypeInHeader = true;
    }


    // body: a string which is either a plain text, JSON object, or a base64 encoded string for binary data (default is "")
    // body is considered empty if it is null, "", or undefined
    if (result.response.body !== undefined) {
        body = result.response.body;
        delete body['main'];
        delete body['code'];
        delete body['binary'];
    }

    //When the content-type is defined, check if the response is binary data or
    // plain text and decode the plain text using a base64 decoder whenever needed.
    // Should the body fail to decoded correctly, return an error to the caller.
    if (contentTypeInHeader && headers[CONTENT_TYPE].lastIndexOf("image", 0) === 0) {
        if (typeof body === "string") {
            body = Buffer.from(body, 'base64')
            headers["Content-Transfer-Encoding"] = "binary";
        }
        // TODO: throw an error if body can not be decoded
    }


    // statusCode: set it to 204 No Content if body is empty
    if (statusCode === 200 && body === "") {
        statusCode = 204;
    }

    if (!headers.hasOwnProperty('Access-Control-Allow-Origin')) {
        headers['Access-Control-Allow-Origin'] = '*';
    }
    if (!headers.hasOwnProperty('Access-Control-Allow-Methods')) {
        headers['Access-Control-Allow-Methods'] = 'OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH';
    }
    // the header Access-Control-Request-Headers is echoed back as the header Access-Control-Allow-Headers if it is present in the HTTP request.
    // Otherwise, a default value is generated.
    if (!headers.hasOwnProperty['Access-Control-Allow-Headers']) {
        headers['Access-Control-Allow-Headers'] = 'Authorization, Origin, X - Requested - With, Content - Type, Accept, User - Agent';
        if (typeof req.headers['Access-Control-Request-Headers'] !== "undefined") {
            headers['Access-Control-Allow-Headers'] = req.headers['Access-Control-Request-Headers'];
        }
    }

    res.header(headers).status(statusCode).send(body);
    DEBUG.functionEnd();
}

function PlatformKnativeImpl(platformFactory) {
    DEBUG.functionStart();
    DEBUG.dumpObject(platformFactory, "platformFactory" );

    var http_method = {
        get: 'GET',
        post: 'POST',
        put: 'PUT',
        delete: 'DELETE',
        options: 'OPTIONS',
    };

    const DEFAULT_METHOD = [ 'POST' ];

    // Provide access to common runtime services
    var service = platformFactory.service;

    // TODO: Should we use app.WrapEndpoint()?
    this.run = function(req, res) {

        try {
            DEBUG.dumpObject(service.initialized(),"service.initialized()");

            // Do not process requests with init. data if this is not a "stem" cell
            if (hasInitData(req) && !isStemCell(process.env))
                throw ("Cannot initialize a runtime with a dedicated function.");

            if(hasInitData(req) && hasActivationData(req)){

                // Process request and process env. variables to provide them in the manner
                // an OpenWhisk Action expects them, as well as enable additional Http features.
                preProcessRequest(req);

                service.initCode(req).then(function () {
                    // delete any INIT data (e.g., code, raw, etc.) from the 'value' data before calling run().
                    removeInitData(req.body);
                    service.runCode(req).then(function (result) {
                        postProcessResponse(req, result, res)
                    });
                }).catch(function (error) {
                    console.error(error);
                    if (typeof error.code === "number" && typeof error.response !== "undefined") {
                        res.status(error.code).json(error.response);
                    } else {
                        console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
                        res.status(500).json({ error: "Internal error during function execution." });
                    }
                });
            } else if(hasInitData(req)){

                // Process request and process env. variables to provide them in the manner
                // an OpenWhisk Action expects them, as well as enable additional Http features.
                preProcessRequest(req);

                service.initCode(req).then(function (result) {
                    res.status(result.code).send(result.response);
                }).catch(function (error) {
                    console.error(error);
                    if (typeof error.code === "number" && typeof error.response !== "undefined") {
                        res.status(error.code).json(error.response);
                    } else {
                        console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
                        res.status(500).json({ error: "Internal error during function execution." });
                    }
                });
            } else if(hasActivationData(req)){
                // Process request and process env. variables to provide them in the manner
                // an OpenWhisk Action expects them, as well as enable additional Http features.
                preProcessRequest(req);

                service.runCode(req).then(function (result) {
                    postProcessResponse(req, result, res)
                }).catch(function (error) {
                    console.error(error);
                    if (typeof error.code === "number" && typeof error.response !== "undefined") {
                        res.status(error.code).json(error.response);
                    } else {
                        console.error("[wrapEndpoint]", "invalid errored promise", JSON.stringify(error));
                        res.status(500).json({ error: "Internal error during function execution." });
                    }
                });
            }

        } catch (e) {
            res.status(500).json({error: "internal error during function initialization."})
        }
    };

    // TODO: the 'httpMethods' var should not alternatively store string and string[] types
    this.registerHandlers = function(app, platform) {
        var httpMethods = process.env.__OW_HTTP_METHODS;
        // default to "[post]" HTTP method if not defined
        if (typeof httpMethods === "undefined") {
            console.error("__OW_HTTP_METHODS is undefined; defaulting to '[post]' ...");
            httpMethods = DEFAULT_METHOD;
        } else {
            if (httpMethods.startsWith('[') && httpMethods.endsWith(']')) {
                httpMethods = httpMethods.substr(1, httpMethods.length);
                httpMethods = httpMethods.substr(0, httpMethods.length -1);
                httpMethods = httpMethods.split(',');
            }
        }
        // default to "[post]" HTTP method if specified methods are not valid
        if (!Array.isArray(httpMethods) || !Array.length) {
            console.error("__OW_HTTP_METHODS is undefined; defaulting to '[post]' ...");
            httpMethods = DEFAULT_METHOD;
        }

        httpMethods.forEach(function (method) {
            switch (method.toUpperCase()) {
                case http_method.get:
                    app.get('/', platform.run);
                    break;
                case http_method.post:
                    app.post('/', platform.run);
                    break;
                case http_method.put:
                    app.put('/', platform.run);
                    break;
                case http_method.delete:
                    app.delete('/', platform.run);
                    break;
                case http_method.options:
                    app.options('/', platform.run);
                    break;
                default:
                    console.error("Environment variable '__OW_HTTP_METHODS' has an unrecognized value (" + method + ").");
            }
        });
    };
    DEBUG.functionEnd();
}

module.exports = PlatformKnativeImpl;
