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

/* eslint-disable strict */

// agent that forwards invocations to the developer's computer by storing them in the
// activation db using simple "echo.js" actions (_wskdebug_invoked & _wskdebug_completed),
// and polling the activation db for those

const openwhisk = require('openwhisk');

const activationListFilterOnlyBasename = false;

function outOfTime(deadline) {
    // stop 10 seconds before timeout, to have enough buffer
    return (Date.now() >= ((deadline || process.env.__OW_DEADLINE) - 10*1000));
}

async function sleep(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

function removePrefix(str, prefix) {
    if (str.startsWith(prefix)) {
        return str.substring(prefix.length);
    }
    return str;
}

function actionName() {
    return removePrefix(process.env.__OW_ACTION_NAME, `/${process.env.__OW_NAMESPACE}/`);
}

async function newActivation(args) {
    args.$activationId = process.env.__OW_ACTIVATION_ID;
    await openwhisk().actions.invoke({
        name: `${actionName()}_wskdebug_invoked`,
        params: args
    });
    return args.$activationId;
}

async function pollActivations(actionName, onActivation, onLoop) {
    const wsk = openwhisk();

    const since = Date.now();

    while (true) {

        let name = actionName;
        if (activationListFilterOnlyBasename) {
            if (actionName.includes("/")) {
                name = actionName.substring(actionName.lastIndexOf("/") + 1);
            }
        }

        const activations = await wsk.activations.list({
            name: name,
            since: since,
            docs: true // include results
        });

        for (const a of activations) {
            const result = onActivation(a);
            if (result) {
                return result;
            }
        }

        await sleep(1000);

        onLoop();
    }
}

async function waitForCompletion(activationId) {
    return pollActivations(
        `${actionName()}_wskdebug_completed`,
        a => {
            // find the one with the $activationId we are waiting on
            if (a.response && a.response.result &&
                a.response.result.$activationId === activationId) {
                const result = a.response.result;
                delete result.$activationId;
                return result;
            }
        },
        () => {
            if (outOfTime()) {
                throw new Error(`Debugger did not complete activation within timeout.`);
            }
        }
    );
}

// Note: this function is duplicated by all agents
function hit(args, condition) {
    if (condition) {
        console.log("arguments:", args);
        console.log("evaluating hit condition: ", condition);
        // eslint-disable-next-line no-with
        with (args) { // lgtm [js/with-statement]
            try {
                // eslint-disable-next-line no-eval
                return eval(condition);
            } catch (e) {
                console.log("failed to eval condition:", e);
                // be safe: do not hit if error in condition
                return false;
            }
        }
    } else {
        // no condition => always hit
        return true;
    }
}

async function doMain(args) {
    // normal activation: make activation available to debugger
    console.log("activation");

    if (hit(args, args.$condition)) {
        console.log("passing on to debugger");
        const id = await newActivation(args);
        return waitForCompletion( id );

    } else {
        console.log("condition evaluated to false, executing original action");
        return openwhisk().actions.invoke({
            name: `${process.env.__OW_ACTION_NAME}_wskdebug_original`,
            params: args,
            blocking: true,
            result: true
        });
    }
}

// OpenWhisk does not like raw exceptions, the error object should be the string message only
// eslint-disable-next-line no-unused-vars
async function main(args) {
    try {
        return await doMain(args);
    } catch (e) {
        console.log("Exception:", e);
        return Promise.reject({ error: e.message, code: e.code});
    }
}
