/*
 * 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();

var NodeActionRunner = require('../runner');

function NodeActionService(cfg) {

    var Status = {
        ready: 'ready',
        starting: 'starting',
        running: 'running',
        stopped: 'stopped'
    };

    var config = cfg;

    // TODO: save the entire configuration for use by any of the route handlers
    var status = Status.ready;
    var ignoreRunStatus = config.allowConcurrent === undefined ? false : config.allowConcurrent.toLowerCase() === "true";
    var server = undefined;
    var userCodeRunner = undefined;
    DEBUG.trace("Initialize: status=" + status);
    DEBUG.trace("Initialize: ignoreRunStatus=" + ignoreRunStatus);

    function setStatus(newStatus) {
        DEBUG.functionStart("newStatus=" + newStatus + " (oldStatus=" + status + ")");
        if (status !== Status.stopped) {
            status = newStatus;
        }
        DEBUG.functionEnd("status=" + status);
    }

    /**
     * An ad-hoc format for the endpoints returning a Promise representing,
     * eventually, an HTTP response.
     *
     * The promised values (whether successful or not) have the form:
     * { code: int, response: object }
     *
     */
    function responseMessage (code, response) {
        return { code: code, response: response };
    }

    function errorMessage (code, errorMsg) {
        return responseMessage(code, { error: errorMsg });
    }

    /**
     * Starts the server.
     *
     * @param app express app
     */
    this.start = function start(app) {
        DEBUG.functionStart();
        server = app.listen(config.port, function() {
            var host = server.address().address;
            var port = server.address().port;
            DEBUG.trace("listening: host: [" + host + "], port: [" + port + "]", "Express (callback)");
        });

        // This is required as http server will auto disconnect in 2 minutes, this to not auto disconnect at all
        server.timeout = 0;
        DEBUG.dumpObject(server, "server");
        DEBUG.functionEnd();
    };

    /** Returns a promise of a response to the /init invocation.
     *
     *  req.body = { main: String, code: String, binary: Boolean }
     */
    this.initCode = function initCode(req) {
        DEBUG.functionStart("status=" + status);

        if (status === Status.ready && userCodeRunner === undefined) {

            setStatus(Status.starting);

            var body = req.body || {};
            var message = body.value || {};
            DEBUG.dumpObject(body,"body");
            DEBUG.dumpObject(message,"message");

            if (message.main && message.code && typeof message.main === 'string' && typeof message.code === 'string') {
                return doInit(message).then(function (result) {
                    setStatus(Status.ready);
                    DEBUG.dumpObject(result, "result","initCode");
                    DEBUG.functionEndSuccess("[200] { OK: true }", "initCode");
                    return responseMessage(200, { OK: true });
                }).catch(function (error) {
                    setStatus(Status.stopped);
                    var errStr = "Initialization has failed due to: " + error.stack ? String(error.stack) : error;
                    DEBUG.functionEndError("[502] " + errStr, "initCode");
                    return Promise.reject(errorMessage(502, errStr));
                });
            } else {
                setStatus(Status.ready);
                var msg = "Missing main/no code to execute.";
                console.error("Internal system error:", msg);
                DEBUG.functionEndError("[403] " + msg);
                return Promise.reject(errorMessage(403, msg));
            }
        } else if (userCodeRunner !== undefined) {
            var msg = "Cannot initialize the action more than once.";
            console.error("Internal system error:", msg);
            DEBUG.functionEndError("[403] " + msg);
            return Promise.reject(errorMessage(403, msg));
        } else {
            var msg = "System not ready, status is " + status + ".";
            console.error("Internal system error:", msg);
            DEBUG.functionEndError("[403] " + msg);
            return Promise.reject(errorMessage(403, msg));
        }
    };

    /**
     * Returns a promise of a response to the /exec invocation.
     * Note that the promise is failed if and only if there was an unhandled error
     * (the user code threw an exception, or our proxy had an internal error).
     * Actions returning { error: ... } are modeled as a Promise successful resolution.
     *
     * req.body = { value: Object, meta { activationId : int } }
     */
    this.runCode = function runCode(req) {
        DEBUG.functionStart("status=" + status);
        DEBUG.dumpObject(req, "request");
        if (status === Status.ready) {
            if (!ignoreRunStatus) {
                setStatus(Status.running);
            }

            return doRun(req).then(function (result) {
                if (!ignoreRunStatus) {
                    setStatus(Status.ready);
                }
                DEBUG.dumpObject(result, "result", "runCode");
                if (typeof result !== "object") {
                    DEBUG.functionEndError("[502] The action did not return a dictionary.","runCode");
                    return errorMessage(502, "The action did not return a dictionary.");
                } else {
                    DEBUG.functionEndSuccess("[200] result: " + result, "runCode");
                    return responseMessage(200, result);
                }
            }).catch(function (error) {
                var msg = "An error has occurred: " + error;
                setStatus(Status.stopped);
                DEBUG.functionEndError("[502]: " + msg);
                return Promise.reject(errorMessage(502, msg));
            });
        } else {
            var msg = "System not ready, status is " + status + ".";
            console.error("Internal system error:", msg);
            DEBUG.functionEndError("[403] " + msg);
            return Promise.reject(errorMessage(403, msg));
        }
    };

    function doInit(message) {
        userCodeRunner = new NodeActionRunner();

        DEBUG.functionStart();
        DEBUG.dumpObject(message,"message")
        return userCodeRunner.init(message).then(function (result) {
            // 'true' has no particular meaning here. The fact that the promise
            // is resolved successfully in itself carries the intended message
            // that initialization succeeded.
            DEBUG.functionEndSuccess("userCodeRunner.init() Success");
            return true;
        }).catch(function (error) {
            // emit error to activation log then flush the logs as this
            // is the end of the activation
            console.error('Error during initialization:', error);
            writeMarkers();
            DEBUG.functionEndError("userCodeRunner.init() Error: " + error);
            return Promise.reject(error);
        });
    }

    function doRun(req) {
        DEBUG.functionStart();
        DEBUG.dumpObject(req,"request");
        var msg = req && req.body || {};
        DEBUG.dumpObject(msg,"msg");
        DEBUG.trace("Adding process environment variables:");
        // Move per-activation keys to process env. vars with __OW_ (reserved) prefix)
        Object.keys(msg).forEach(
            function (k) {
                if(typeof msg[k] === 'string' && k !== 'value'){
                    var envVariable = '__OW_' + k.toUpperCase();
                    process.env['__OW_' + k.toUpperCase()] = msg[k];
                    DEBUG.dumpObject(process.env[envVariable], envVariable, "doRun");
                }
            }
        );

        return userCodeRunner.run(msg.value).then(function(result) {
            if (typeof result !== "object") {
                console.error('Result must be of type object but has type "' + typeof result + '":', result);
            }
            writeMarkers();
            DEBUG.functionEndSuccess("userCodeRunner.run(): Success (" + result + ")", "doRun");
            return result;
        }).catch(function (error) {
            console.error(error);
            writeMarkers();
            DEBUG.functionEndError("userCodeRunner.run(): Error:" + error, "doRun");
            return Promise.reject(error);
        });
    }

    function writeMarkers() {
        console.log('XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX');
        console.error('XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX');
    }
}

NodeActionService.getService = function(config) {
    return new NodeActionService(config);
};

module.exports = NodeActionService;
