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

function DebuggerClient() {
  this.DEBUGGER_DETACHED = 0;
  this.DEBUGGER_ATTACHING = 1;
  this.DEBUGGER_ATTACHED = 2;
  this.scripts = [];
  this.attachState = this.DEBUGGER_DETACHED;
  this.onAttachCallback = this.onAttach.bind(this);
  this.onEventCallback = this.onEvent.bind(this);
  this.executionContext = 0;
}

// Attaches to the debugger and listens for debug events.
// Enables the domains we care about here.
DebuggerClient.prototype.attach = function() {
  if (this.attachState == this.DEBUGGER_DETACHED) {
    this.attachState = this.DEBUGGER_ATTACHING;
    printToMessageLog(messageLog.INTERACTIVE,
                      'Attempting to attach to debugger...');
    this.scripts = [];
    debugHub.debugger.onEvent.addListener(this.onEventCallback);
    debugHub.debugger.attach(this.onAttachCallback);
    this.sendCommand('Console.enable');
    this.sendCommand('Runtime.enable');
  } else if (this.attachState == this.DEBUGGER_ATTACHING) {
    printToMessageLog(messageLog.INTERACTIVE,
                      'Still attempting to attach to debugger...');
  }
}

// Local method to 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.
DebuggerClient.prototype.getScripts = function(scriptId) {
  for (var i in this.scripts) {
    var index = this.pad(i, 3);
    var scriptUrl = this.scripts[i].url;
    printToMessageLog(messageLog.INTERACTIVE, index + ': ' + scriptUrl);
  }
}

//--- Commands.

// Each debugger command has an associated callback to get the result.

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

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

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

DebuggerClient.prototype.evaluate = function(expression) {
  var callback = this.evaluateCallback.bind(this);
  var method = 'Runtime.evaluate';
  var params = {};
  params.contextId = this.executionContext;
  params.expression = expression;
  params.generatePreview = true;
  params.includeCommandLineAPI = true;
  params.objectGroup = 'console';
  params.returnByValue = false;
  this.sendCommand(method, params, callback);
}

DebuggerClient.prototype.evaluateCallback = function(result) {
  if (result.wasThrown) {
    printToMessageLog(messageLog.ERROR,
                      'Uncaught ' + result.result.description);
  } else if (result.result.preview) {
    printToMessageLog(messageLog.INFO, result.result.preview.description);
    if (result.result.preview.properties) {
      for (var i = 0; i < result.result.preview.properties.length; ++i) {
        var property = result.result.preview.properties[i];
        printToMessageLog(messageLog.INFO,
                          '  ' + property.name + ': ' + property.value);
      }
    }
    if (result.result.preview.overflow) {
      printToMessageLog(messageLog.INFO, '  ...');
    }
  } else if (result.result.description) {
    printToMessageLog(messageLog.INFO, result.result.description);
  }
  printToMessageLog(messageLog.INFO, '');
}

// All debugger commands are routed through this method. Converts the command
// parameters into a JSON string to pass to the debug server.
DebuggerClient.prototype.sendCommand = function(method, commandParams,
                                                callback) {
  var jsonParams = JSON.stringify(commandParams);
  var commandCallback = this.commandCallback.bind(this, callback);
  debugHub.debugger.sendCommand(method, jsonParams, commandCallback);
}

// All command callbacks are routed through this method. Parses the JSON
// response from the debug server, checks for errors and passes on to the
// command-specific callback to handle the result.
DebuggerClient.prototype.commandCallback = function(callback, responseString) {
  var response = JSON.parse(responseString);

  if (response && response.error) {
    printToMessageLog(messageLog.ERROR, 'Error: ' + response.error.message);
  } else if (callback) {
    if (response) {
      callback(response.result);
    } else {
      callback(null);
    }
  }
}

//-- Events.

DebuggerClient.prototype.onAttach = function() {
  if (debugHub.debugger.lastError) {
    printToMessageLog(messageLog.WARNING, 'Could not attach to debugger.');
    this.attachState = this.DEBUGGER_DETACHED;
  } else {
    printToMessageLog(messageLog.INTERACTIVE, 'Debugger attached.');
    this.attachState = this.DEBUGGER_ATTACHED;
  }
}

// All events generated by the debug server are routed through this method.
// Parses the JSON string and passes on to the appropriate handler according to
// the method name.
DebuggerClient.prototype.onEvent = function(method, paramString) {
  var params = JSON.parse(paramString);
  if (method == 'Debugger.scriptParsed') {
    this.onScriptParsed(params);
  } else if (method == 'Inspector.detached') {
    this.onDetached(params);
  } else if (method == 'Runtime.executionContextCreated') {
    this.onExecutionContextCreated(params);
  }
}

DebuggerClient.prototype.onDetached = function() {
  printToMessageLog(messageLog.INTERACTIVE, 'Debugger detached.');
  this.attachState = this.DEBUGGER_DETACHED;
}

DebuggerClient.prototype.onExecutionContextCreated = function(params) {
  this.executionContext = params.context.id;
  printToMessageLog(messageLog.INFO,
                    'Execution context created: ' + this.executionContext);
}

DebuggerClient.prototype.onScriptParsed = function(params) {
  this.scripts.push(params);
}

//--- Utils.

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