// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed 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 scripts = [];
var commandCallbacks = [];
var nextRequestId = 0;

function help(command) {
  var helpString = '';
  if (command) {
    helpString = 'Command-specific help not available.\n\n';
  } else {
    // Summary help for all commands.
    helpString += 'Commands:\n\n';
    helpString += 'history: Show command history.\n';
    helpString += 'attach: Attach to remote debugger at specified host' +
                  '(default = localhost:9222).\n';
    helpString += 'detach: Close the connection to the remote debugger.\n';
    helpString += 'getScripts: List the scripts that have been parsed.\n';
    helpString += 'getScriptSource: Show the source of a specific script.\n';
    helpString += 'sendCommand: Send an arbitrary command to the debug ' +
                  'server.\n';
    helpString +=
        '\nYou are entering JavaScript, so remember to use parentheses, ' +
        'enclose string arguments in quotes, etc.\n';
  }
  printToMessageLog(messageLog.INTERACTIVE, helpString);
}

function history() {
  var history = commandInput.getHistory();
  for (var i = 0; i < history.length; i += 1) {
    printToMessageLog(messageLog.INTERACTIVE, i + ' ' + history[i]);
  }
}

// Attaches to the debugger and listens for debug events.
function attach(host) {
  printToMessageLog(messageLog.LOCAL, 'Attaching...');
  if (!host) {
    host = 'localhost:9222';
  }
  try {
    resetConnection();
    connection = new WebSocket('ws://' + host);
    connection.onopen = onOpen;
    connection.onmessage = onMessage;
    connection.onerror = onError;
    connection.onclose = onClose;
  } catch (error) {
    printToMessageLog(messageLog.ERROR, "Error: " + JSON.stringify(error));
  }
}

// Closes the current connection, if any.
function detach() {
  if (connection) {
    connection.close();
    resetConnection();
  } else {
    printToMessageLog(messageLog.WARNING, 'Not currently attached.');
  }
}

// List the parsed scripts the client has been notifed of
// via the |Debugger.scriptParsed| event. Maps the possibly very long script id
// from the debug server to a more human-readable 0-based index.
function getScripts() {
  for (var i in scripts) {
    var index = pad(i, 3);
    var scriptUrl = scripts[i].url;
    printToMessageLog(messageLog.LOCAL, index + ': ' + scriptUrl);
  }
}

// Commands; each may have an associated callback.

function getScriptSource(scriptId) {
  // If the id looks like an index into the local script array,
  // look up the real id there.
  if (scriptId >= 0 && scriptId < this.scripts.length) {
    scriptId = this.scripts[scriptId].scriptId;
  }

  var method = 'Debugger.getScriptSource'
  var params = { 'scriptId': scriptId.toString() };
  var callback = getScriptSourceCallback;
  this.sendCommand(method, params, callback);
}

function getScriptSourceCallback(result) {
  var scriptSource = result.scriptSource;
  var lines = scriptSource.split('\n');
  for (var i = 0; i < lines.length; i++) {
    var index = pad(i + 1, 4);
    printToMessageLog(messageLog.LOCAL, index + ': ' + lines[i]);
  }
}

// Generic method to send a command to the debug web server with
// optional callback.
function sendCommand(method, params, callback) {
  if (connection) {
    try {
      var request = {};
      request.id = nextRequestId++;
      request.method = method;
      request.params = params;
      var json = JSON.stringify(request);
      commandCallbacks[request.id] = callback;
      printToMessageLog(messageLog.LOCAL, json);
      connection.send(json);
    } catch (error) {
      printToMessageLog(messageLog.ERROR, error.toString());
    }
  } else {
    printToMessageLog(messageLog.WARNING,
                      'No connection - please call attach() first.');
  }
}

//--- Response and notification handlers.

function onResponse(response) {
  if (commandCallbacks[response.id]) {
    commandCallbacks[response.id](response.result);
    commandCallbacks[response.id] = null;
  }
}

function onNotification(notification) {
  if (notification.method == 'Debugger.scriptParsed') {
    this.onScriptParsed(notification.params);
  }
}

function onScriptParsed(params) {
  scripts.push(params);
}

//--- Debugger events.

function onOpen() {
  printToMessageLog(messageLog.NOTIFICATION, 'Attached.');
}

function onMessage(message) {
  var data = JSON.parse(message.data);
  if (data.error) {
    printToMessageLog(messageLog.ERROR, message.data);
  } else if (data.id != undefined && data.id != null) {
    printToMessageLog(messageLog.RESPONSE, message.data);
    onResponse(data);
  } else {
    printToMessageLog(messageLog.NOTIFICATION, message.data);
    onNotification(data);
  }
}

function onError(error) {
  printToMessageLog(messageLog.ERROR, 'Server Error: ' + JSON.stringify(error));
}

function onClose() {
  printToMessageLog(messageLog.WARNING, 'Connection closed.');
  resetConnection();
}

//--- Utils.

function pad(number, minLength) {
  var result = number.toString();
  while (result.length < minLength) {
    result = ' ' + result;
  }
  return result;
}

function resetConnection() {
  connection = null;
  scripts = [];
  nextRequestId = 0;
}