/*
 * 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 argv = require('argv'),
    repl = require('./repl').repl,
    colors = require('colors'),
    events = require('events'),
    package = require('../package.json'),
    eventBus = new events.EventEmitter(),
    WebSocket = require('ws'),
    debugNodeJS = require('./debug-nodejs').debug,
    debugSwift = require('./debug-swift').debug,
    debugPython = require('./debug-python').debug,
    expandHomeDir = require('expand-home-dir'),
    propertiesParser = require('properties-parser'),

    api = {
    host: 'https://openwhisk.ng.bluemix.net',
    path: '/api/v1'
    },
    broker = {
    host: 'https://owdbg-broker.mybluemix.net',
    path: '/ws/client/register'
    };

exports.main = function() {

var commandLineOptionsConfig = [
    {name: 'use-cli-debugger', short: 'c', type: 'string', description: 'Favor the CLI for debug sessions over a GUI'},
    {name: 'python', short: 'p', type: 'string', description: 'Include python support'},
    {name: 'dev', short: 'd', type: 'string', description: 'Set up wskdb as a developer'},
    {name: 'reset', short: 'r', type: 'string', description: 'Reset wskdb, so that the dependencies are reinstalled'},
    {name: 'verbose', type: 'string', description: 'Log activity more verbosely'},
    {name: 'no-color', type: 'string', description: 'Avoid using console colors'} // this comes from the colors module
];
argv.info('Usage: wskdb [attachTo] [options...]'.red + '\n\nWhere each option is one of the following:');
argv.version(package.version);
var commandLineOptions = argv
    .option(commandLineOptionsConfig)
    .run()
    .options;

var ws = new WebSocket(broker.host + broker.path);

ws.on('open', function open() {
    console.log('Welcome to the OpenWhisk Debugger'.red);

    if (commandLineOptions) {
    for (var x in commandLineOptions) {
        if (commandLineOptions.hasOwnProperty(x)) {
        console.log(('    + ' + commandLineOptionsConfig.find((o) => o.name === x).description).dim);
        }
    }
    }
    console.log();

    var wskprops = propertiesParser.read(expandHomeDir('~/.wskprops'));
    if (!wskprops.NAMESPACE) {
    wskprops.NAMESPACE = '_';
    }
    var key = wskprops.AUTH;
    ws.send(JSON.stringify({
    type: 'init',
    key: key
    }));

    var keepAlive = setInterval(function poke() {
    try {
        ws.send(JSON.stringify({
        type: 'keep-alive'
        }));
    } catch (e) {
        console.error();
        console.error('It looks like your network went offline. Please restart wskdb when your network is live.');
        process.exit(1);
    }
    }, 5000);

    process.on('SIGINT', () => {
    //
    // clean up all stubs
    //
    console.log('Cleaning up');
    require('./rewriter').clean(wskprops, process.exit); // note: clean versus detachAll
    });

    process.on('exit', function onExit() {
    try {
        // console.log('Goodbye!'.red);
        clearInterval(keepAlive);

        ws.send(JSON.stringify({
        type: 'disconnect'
        }, function ack() {
        ws.close();
        }));
    } catch (e) {
    }
    });

    //
    // does the user want to attach to an action right up front?
    //
    var attachTo;
    try {
    attachTo = process.argv.slice(2).find(arg => {
        arg = arg.replace(/-/g, '');
        return !commandLineOptions.hasOwnProperty(arg) // not a long option
        && !commandLineOptionsConfig.find(opt => opt.short === arg); // and not a short option
    });
    } catch (e) {
    // uncomment this for debugging:
    // console.error('error',e);
    }

    repl(wskprops, eventBus, attachTo);
});

ws.on('close', function() {
    //console.log('Remote connection closed');
});

    var debugInProgress = false;
    eventBus.on('invocation-done', () => {
    console.log('Debug session complete');
    debugInProgress = false;
    });

ws.on('message', function(data, flags) {
    //console.log('MESSAGE ' + data + ' ||| ' + JSON.stringify(flags));

    //
    // flags.binary will be set if a binary data is received.
    // flags.masked will be set if the data was masked.
    //
    try {
    var message = JSON.parse(data);
    switch (message.type) {
    case 'invoke':
        var circuitBreaker = function circuitBreaker() {
        ws.send(JSON.stringify({
            type: 'circuit-breaker',
            key: message.key,
            activationId: message.activationId,
        }));
        };

        if (debugInProgress) {
        return circuitBreaker();
        }

        debugInProgress = true;

        console.log('Debug session requested');
        // console.log(JSON.stringify(message, undefined, 4));

        var done = function done(err, result) {
        // console.log('Finishing up this debug session');

        ws.send(JSON.stringify({
            type: err ? 'circuit-breaker' : 'end',
            key: message.key,
            activationId: message.activationId,
            result: result
        }));

        //ws.close();
        };

        if (message.onDone_trigger) {
        if (message.action && message.action.exec) {
            var kind = message.action.exec.kind;
            var debugHandler;

            if (!kind || kind.indexOf('nodejs') >= 0) {
            // !kind because nodejs is the default
            debugHandler = debugNodeJS;
            } else if (kind.indexOf('swift') >= 0) {
            debugHandler = debugSwift;
            } else if (kind.indexOf('python') >= 0) {
            debugHandler = debugPython;
            }

            if (debugHandler) {
            debugHandler(message, ws, { trigger: message.onDone_trigger }, done, commandLineOptions, eventBus);
            } else {
            console.error('Unable to complete invocation, because this action\'s kind is not yet handled: ' + kind);
            circuitBreaker();
            }

        } else {
            console.error('Unable to complete invocation: no action code to debug');
            circuitBreaker();
        }
        } else {
        console.error('Unable to complete invocation: no onDone_trigger specified');
        circuitBreaker();
        }

        break;
    }
    } catch (e) {
    console.log(e);
    }
});

/*
sending binary data
ws.on('open', function open() {
  var array = new Float32Array(5);

  for (var i = 0; i < array.length; ++i) {
    array[i] = i / 2;
  }

  ws.send(array, { binary: true, mask: true });
});
*/

}; /* end of exports.main() */
