/*
 * 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'."
    });
    yargs.option("cleanup", {
        type: "boolean",
        group: "Agent options:",
        describe: "Remove backup and any helper actions on exit. Makes shutdown slower."
    });
    yargs.option("ignore-certs", {
        type: "boolean",
        group: "Agent options:",
        describe: "Bypass TLS certificate checking for openwhisk requests."
    });

    // 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;
