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

'use strict';

const yargs = require("yargs");
const Debugger = require("./src/debugger");
const path = require("path");
const fs = require("fs");
const debug = require('./src/debug');

function enableConsoleColors() {
    // colorful console.error() and co
    let originalConsole = null;
    if (!console._logToFile) {
        originalConsole = {
            log: console.log,
            error: console.error,
            info: console.info,
            debug: console.debug
        };
        // overwrites console.log and co
        require('manakin').global;
    }
    return originalConsole;
}

function resetConsoleColors(originalConsole) {
    if (originalConsole) {
        console.log = originalConsole.log;
        console.error = originalConsole.error;
        console.info = originalConsole.info;
        console.debug = originalConsole.debug;
    }
}

function getSupportedKinds() {
    const kinds = [];
    const basePath = path.resolve(__dirname, "src/kinds");
    fs.readdirSync(basePath).forEach(function(entry) {
        const p = path.resolve(basePath, entry);
        if (fs.statSync(p).isDirectory()) {
            const kind = require(path.resolve(p, entry));
            kinds.push(`${entry}: ${kind.description}`);
        }
    });
    return kinds;
}

function yargsOptions(yargs) {
    yargs.positional('action', {
        describe: 'Name of action to debug',
        type: 'string'
    });
    yargs.positional('source-path', {
        describe: 'Path to local action sources, file or folder (optional)',
        type: 'string'
    });

    // action options
    yargs.option("m", {
        alias: "main",
        type: "string",
        group: "Action options:",
        describe: "Name of action entry point"
    });
    yargs.option("k", {
        alias: "kind",
        type: "string",
        group: "Action options:",
        describe: "Action kind override, needed for blackbox images"
    });
    yargs.option("i", {
        alias: "image",
        type: "string",
        group: "Action options:",
        describe: "Docker image to use as action container"
    });
    yargs.option("on-build", {
        type: "string",
        group: "Action options:",
        describe: "Shell command for custom action build step"
    });
    yargs.option("build-path", {
        type: "string",
        group: "Action options:",
        describe: "Path to built action, result of --on-build command"
    });

    // source watching
    yargs.option("l", {
        type: "boolean",
        implies: "source-path",
        group: "LiveReload options:",
        describe: "Enable browser LiveReload on [source-path]"
    });
    yargs.option("lr-port", {
        type: "number",
        implies: "l",
        group: "LiveReload options:",
        describe: "Port for browser LiveReload (defaults to 35729)"
    });
    yargs.option("P", {
        type: "string",
        group: "LiveReload options:",
        describe: "Invoke action with these parameters on changes to [source-path].\nArgument can be json string or name of json file."
    });
    yargs.option("a", {
        type: "string",
        group: "LiveReload options:",
        describe: "Name of custom action to invoke upon changes to [source-path].\nDefaults to <action> if -P is set."
    });
    yargs.option("r", {
        type: "string",
        group: "LiveReload options:",
        describe: "Shell command to run upon changes to [source-path]"
    });
    yargs.option("watch", {
        type: "string",
        array: true,
        group: "LiveReload options:",
        describe: "Glob pattern(s) to watch for source modifications"
    });
    yargs.option("watch-exts", {
        type: "string",
        array: true,
        group: "LiveReload options:",
        describe: "File extensions to watch for modifications"
    });

    // Debugger options
    yargs.option("p", {
        alias: "port",
        type: "number",
        group: "Debugger options:",
        describe: "Debug port exposed from container that debugging clients connect to. Defaults to --internal-port if set or standard debug port of the kind. Node.js arguments --inspect and co. can be used too."
    });
    yargs.option("internal-port", {
        type: "number",
        group: "Debugger options:",
        describe: "Actual debug port inside the container. Must match port opened by --command. Defaults to standard debug port of kind."
    });
    yargs.option("command", {
        type: "string",
        group: "Debugger options:",
        describe: "Custom container command that enables debugging"
    });
    yargs.option("docker-args", {
        type: "string",
        group: "Debugger options:",
        describe: "Additional docker run arguments for container. Must be quoted and start with space: 'wskdebug --docker-args \" -e key=var\" myaction'"
    });
    yargs.option("on-start", {
        type: "string",
        group: "Debugger options:",
        describe: "Shell command to run when debugger is up"
    });

    // Agent options
    yargs.option("c", {
        alias: "condition",
        type: "string",
        group: "Agent options:",
        describe: "Hit condition to trigger debugger. Javascript expression evaluated against input parameters. Example: 'debug == 'true'"
    });
    yargs.option("agent-timeout", {
        type: "number",
        group: "Agent options:",
        describe: "Debugging agent timeout (seconds). Default: 5 min"
    });
    yargs.option("ngrok", {
        type: "boolean",
        group: "Agent options:",
        describe: "Use 3rd party service ngrok.com for agent forwarding."
    });
    yargs.option("ngrok-region", {
        type: "string",
        group: "Agent options:",
        describe: "Ngrok region to use. Defaults to 'us'."
    });

    // nodejs options
    yargs.option("inspect", {
        alias: ["inspect-brk", "inspect-port", "debug", "debug-brk", "debug-port"],
        hidden: true,
        type: "number"
    });

    // general options
    yargs.option("v", {
        alias: "verbose",
        type: "boolean",
        describe: "Verbose output. Logs activation parameters and result"
    });
    yargs.version(require("./package.json").version);
}

function getYargsParser() {
    return yargs
        .help()
        .alias("h", "help")
        .updateStrings({
            'Positionals:': 'Arguments:',
            'Not enough non-option arguments: got %s, need at least %s': {
                "one": "Error: Missing argument <action> (%s/%s)",
                "other": "Error: Missing argument <action> (%s/%s)"
            }
        })
        .version(false)
        .wrap(90)
        .command(
            "* <action> [source-path]",
            // eslint-disable-next-line indent
           `.            ____      ___                   _    _ _     _     _
            .           /\\   \\    / _ \\ _ __   ___ _ __ | |  | | |__ (_)___| | __
            .      /\\  /__\\   \\  | | | | '_ \\ / _ \\ '_ \\| |  | | '_ \\| / __| |/ /
            .     /  \\____ \\  /  | |_| | |_) |  __/ | | | |/\\| | | | | \\__ \\   <
            .     \\   \\  /  \\/    \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\
            .      \\___\\/ tm           |_|

            .                              W S K D E B U G

            Debug an Apache OpenWhisk <action> by forwarding its activations to a local docker
            container that has debugging enabled and its debug port exposed to the host.

            If only <action> is specified, the deployed action code is debugged.

            If [source-path] is set, it must point to the local action sources which will be mounted
            into the debug container. Sources will be automatically reloaded on each new activation.
            This feature depends on the kind.

            Supported kinds:
            - ${getSupportedKinds().join("\n")}
            `,
            yargsOptions
        );
}

function normalizeArgs(argv) {
    // pass hidden node.js arg aliases to port option
    argv.port = argv.inspect || argv.p;
    // more readable internal argument names
    argv.livereload = argv.l;
    argv.livereloadPort = argv.lrPort;
    argv.invokeParams = argv.P;
    argv.invokeAction = argv.a;
    argv.onChange = argv.r;

    if (process.env.WSK_PACKAGE && argv.action && !argv.action.includes("/")) {
        argv.action = `${process.env.WSK_PACKAGE}/${argv.action}`;
    }
}

function printErrorAndExit(err, argv) {
    console.log();
    if (argv.verbose) {
        console.error(err);
    } else {
        console.error("Error:", err.message);
    }
    process.exit(1);
}

function registerExitHandler(dbg) {
    // ensure we remove the agent when this app gets terminated
    ['SIGINT', 'SIGTERM'].forEach(signal => {
        process.on(signal, async () => {
            await dbg.kill();

            process.exit();
        });
    });
}

async function wskdebug(args, isCommandLine=false) {
    debug("wskdebug arguments:", args);
    const originalConsole = enableConsoleColors();

    try {
        const parser = getYargsParser();

        // if cli mode, we want to exit the process, otherwise throw an error
        parser.showHelpOnFail(isCommandLine);
        parser.exitProcess(isCommandLine);

        const argv = parser.parse(args);
        normalizeArgs(argv);

        if (argv.help || argv.version) {
            // do nothing
            return;
        }

        try {
            const dbg = new Debugger(argv);
            if (isCommandLine) {
                registerExitHandler(dbg);
            }
            await dbg.start();
            await dbg.run();

        } catch (e) {
            if (isCommandLine) {
                printErrorAndExit(e, argv);
            } else {
                throw e;
            }
        }

    } finally {
        resetConsoleColors(originalConsole);
    }
}

// exporting the resulting promise for unit tests
module.exports = wskdebug;
