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

/**
 * Object which encapsulates a first-class function, the user code for
 * an action.
 *
 * This file (runner.js) must currently live in root directory for nodeJsAction.
 */
var util = require('util');
var child_process = require('child_process');
var fs = require('fs');
var path = require('path');
const serializeError = require('serialize-error');

function NodeActionRunner() {
    DEBUG.functionStart();
    // Use this ref inside closures etc.
    var thisRunner = this;

    this.userScriptMain = undefined;

    // This structure is reset for every action invocation. It contains two fields:
    //   - completed; indicating whether the action has already signaled completion
    //   - next; a callback to be invoked with the result of the action.
    // Note that { error: ... } results are still results.
    var callback = {
        completed : undefined,
        next      : function (result) { return; }
    };

    DEBUG.dumpObject(callback,"callback");

    this.init = function(message) {
        DEBUG.functionStart("NodeActionRunner");
        function assertMainIsFunction() {
            DEBUG.dumpObject(thisRunner.userScriptMain,"this.Runner.userScriptMain");
            if (typeof thisRunner.userScriptMain !== 'function') {
                DEBUG.functionEndError("ERROR: Action entrypoint '" + message.main + "' is not a function.");
                throw "Action entrypoint '" + message.main + "' is not a function.";
            }
            DEBUG.functionEnd();
        }

        // Loading the user code.
        DEBUG.dumpObject(message.binary, "message.binary");
        if (message.binary) {
            // The code is a base64-encoded zip file.
            return unzipInTmpDir(message.code).then(function (moduleDir) {
                if(!fs.existsSync(path.join(moduleDir, 'package.json')) &&
                    !fs.existsSync(path.join(moduleDir, 'index.js'))) {
                    DEBUG.functionEndError("Promise.reject(): Zipped actions must contain either package.json or index.js at the root.");
                    return Promise.reject('Zipped actions must contain either package.json or index.js at the root.')
                }

                try {
                    // Set the executable directory to the project dir
                    process.chdir(moduleDir);
                    thisRunner.userScriptMain = eval('require("' + moduleDir + '").' + message.main);
                    assertMainIsFunction();
                    // The value 'true' has no special meaning here;
                    // the successful state is fully reflected in the
                    // successful resolution of the promise.
                    DEBUG.functionEndSuccess("return true;");
                    return true;
                } catch (e) {
                    DEBUG.functionEndError("Promise.reject(): " + e.message);
                    return Promise.reject(e);
                }
            }).catch(function (error) {
                DEBUG.functionEndError("Promise.reject(): " + error.message);
                return Promise.reject(error);
            });
        } else {
            // The code is a plain old JS file.
            try {
                thisRunner.userScriptMain = eval('(function(){' + message.code + '\nreturn ' + message.main + '})()');
                DEBUG.dumpObject(thisRunner.userScriptMain,"thisRunner.userScriptMain");
                assertMainIsFunction();
                // See comment above about 'true'; it has no specific meaning.
                DEBUG.functionEndSuccess("Promise.resolve(true)");
                return Promise.resolve(true);
            } catch (e) {
                DEBUG.functionEndError("Promise.reject(): " + e.message);
                return Promise.reject(e);
            }
        }
    };

    // Returns a Promise with the result of the user code invocation.
    // The Promise is rejected iff the user code throws.
    this.run = function(args) {
        DEBUG.functionStart();
        return new Promise(
            function (resolve, reject) {
                callback.completed = undefined;
                callback.next = resolve;

                try {
                    DEBUG.dumpObject(args, "Calling: thisRunner.userScriptMain(args): args", "run");
                    var result = thisRunner.userScriptMain(args);
                    DEBUG.dumpObject(result,"Returned: thisRunner.userScriptMain(args): result", "run");
                } catch (e) {
                    DEBUG.functionEndError("ERROR: Promise.reject(): " + e.message);
                    reject(e);
                }

                // Non-promises/undefined instantly resolve.
                Promise.resolve(result).then(function (resolvedResult) {
                    // This happens, e.g. if you just have "return;"
                    if (typeof resolvedResult === "undefined") {
                        resolvedResult = {};
                    }
                    DEBUG.functionEndSuccess("Promise.Resolve(): result=" + resolvedResult, "run");
                    resolve(resolvedResult);
                }).catch(function (error) {
                    // A rejected Promise from the user code maps into a
                    // successful promise wrapping a whisk-encoded error.

                    // Special case if the user just called `reject()`.
                    if (!error) {
                        DEBUG.functionEndError("ERROR: reject()", "run");
                        resolve({ error: {}});
                    } else {
                        DEBUG.functionEndError("ERROR: " + error.message, "run");
                        resolve({ error: serializeError(error) });
                    }
                });
            }
        );
    };

    // Helper function to copy a base64-encoded zip file to a temporary location,
    // decompress it into temporary directory, and return the name of that directory.
    // Note that this makes heavy use of shell commands because:
    //   1) Node 0.12 doesn't have many of the useful fs functions.
    //   2) We know in which environment we're running.
    function unzipInTmpDir(base64) {
        DEBUG.functionStart();
        var mkTempCmd = "mktemp -d XXXXXXXX";
        return exec(mkTempCmd).then(function (tmpDir1) {
            return new Promise(
                function (resolve, reject) {
                    var zipFile = path.join(tmpDir1, "action.zip");
                    fs.writeFile(zipFile, base64, "base64", function (err) {
                        if (err) {
                            DEBUG.functionEndError("Promise.reject: " + err.message);
                            reject("There was an error reading the action archive.");
                        }
                        DEBUG.functionEndSuccess("Promise.resolve: zipFile=" + zipFile);
                        resolve(zipFile);
                    });
                }
            );
        }).then(function (zipFile) {
            return exec(mkTempCmd).then(function (tmpDir2) {
                return exec("unzip -qq " + zipFile + " -d " + tmpDir2).then(function (res) {
                    DEBUG.functionEndSuccess("Promise.resolve: tmpDir2=" + tmpDir2);
                    return path.resolve(tmpDir2);
                }).catch(function (error) {
                    DEBUG.functionEndError("Promise.reject: " + error.message);
                    return Promise.reject("There was an error uncompressing the action archive.");
                });
            });
        });
    }

    // Helper function to run shell commands.
    function exec(cmd) {
        DEBUG.functionStart();
        return new Promise(
            function (resolve, reject) {
                child_process.exec(cmd, function (error, stdout, stderr) {
                    DEBUG.dumpObject(cmd,"cmd");
                    if (error) {
                        DEBUG.functionEndError("Promise.reject: " + error.message);
                        reject(stderr.trim());
                    } else {
                        DEBUG.functionEndSuccess("Promise.resolve");
                        resolve(stdout.trim());
                    }
                });
            }
        );
    }
}

module.exports = NodeActionRunner;
