// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview
 * Module to format IQ messages so they can be displayed in the debug log.
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/**
 * @constructor
 */
remoting.FormatIq = function() {
  this.clientJid = '';
  this.hostJid = '';
};

/**
 * Verify that the only attributes on the given |node| are those specified
 * in the |attrs| string.
 *
 * @param {Node} node The node to verify.
 * @param {string} validAttrs Comma-separated list of valid attributes.
 *
 * @return {boolean} True if the node contains only valid attributes.
 */
remoting.FormatIq.prototype.verifyAttributes = function(node, validAttrs) {
  var attrs = ',' + validAttrs + ',';
  var len = node.attributes.length;
  for (var i = 0; i < len; i++) {
    /** @type {Node} */
    var attrNode = node.attributes[i];
    var attr = attrNode.nodeName;
    if (attrs.indexOf(',' + attr + ',') == -1) {
      return false;
    }
  }
  return true;
};

/**
 * Record the client and host JIDs so that we can check them against the
 * params in the IQ packets.
 *
 * @param {string} clientJid The client JID string.
 * @param {string} hostJid The host JID string.
 */
remoting.FormatIq.prototype.setJids = function(clientJid, hostJid) {
  this.clientJid = clientJid;
  this.hostJid = hostJid;
};

/**
 * Calculate the 'pretty' version of data from the |server| node.
 *
 * @param {Node} server Xml node with server info.
 *
 * @return {?string} Formatted server string. Null if error.
 */
remoting.FormatIq.prototype.calcServerString = function(server) {
  if (!this.verifyAttributes(server, 'host,udp,tcp,tcpssl')) {
    return null;
  }
  var host = server.getAttribute('host');
  var udp = server.getAttribute('udp');
  var tcp = server.getAttribute('tcp');
  var tcpssl = server.getAttribute('tcpssl');

  var str = "'" + host + "'";
  if (udp)
    str += ' udp:' + udp;
  if (tcp)
    str += ' tcp:' + tcp;
  if (tcpssl)
    str += ' tcpssl:' + tcpssl;

  str += '; ';
  return str;
};

/**
 * Calc the 'pretty' version of channel data.
 *
 * @param {Node} channel Xml node with channel info.
 *
 * @return {?string} Formatted channel string. Null if error.
 */
remoting.FormatIq.prototype.calcChannelString = function(channel) {
  var name = channel.nodeName;
  if (!this.verifyAttributes(channel, 'transport,version,codec')) {
    return null;
  }
  var transport = channel.getAttribute('transport');
  var version = channel.getAttribute('version');

  var str = name + ' ' + transport + ' v' + version;
  if (name == 'video') {
    str += ' codec=' + channel.getAttribute('codec');
  }
  str += '; ';
  return str;
};

/**
 * Pretty print the jingleinfo from the given Xml node.
 *
 * @param {Node} query Xml query node with jingleinfo in the child nodes.
 *
 * @return {?string} Pretty version of jingleinfo. Null if error.
 */
remoting.FormatIq.prototype.prettyJingleinfo = function(query) {
  var nodes = query.childNodes;
  var stun_servers = '';
  var result = '';
  for (var i = 0; i < nodes.length; i++) {
    /** @type {Node} */
    var node = nodes[i];
    var name = node.nodeName;
    if (name == 'stun') {
      var sserver = '';
      var stun_nodes = node.childNodes;
      for(var s = 0; s < stun_nodes.length; s++) {
        /** @type {Node} */
        var stun_node = stun_nodes[s];
        var sname = stun_node.nodeName;
        if (sname == 'server') {
          var stun_str = this.calcServerString(stun_node);
          if (!stun_str) {
            return null;
          }
          sserver += stun_str;
        }
      }
      result += '\n  stun ' + sserver;
    } else if (name == 'relay') {
      var token = '';
      var rserver = '';
      var relay_nodes = node.childNodes;
      for(var r = 0; r < relay_nodes.length; r++) {
        /** @type {Node} */
        var relay_node = relay_nodes[r];
        var rname = relay_node.nodeName;
        if (rname == 'token') {
          token = token + relay_node.textContent;
        }
        if (rname == 'server') {
          var relay_str = this.calcServerString(relay_node);
          if (!relay_str) {
            return null;
          }
          rserver += relay_str;
        }
      }
      result += '\n  relay ' + rserver + ' token: ' + token;
    } else {
      return null;
    }
  }

  return result;
};

/**
 * Pretty print the session-initiate or session-accept info from the given
 * Xml node.
 *
 * @param {Node} jingle Xml node with jingle session-initiate or session-accept
 *                      info contained in child nodes.
 *
 * @return {?string} Pretty version of jingle stanza. Null if error.
 */
remoting.FormatIq.prototype.prettySessionInitiateAccept = function(jingle) {
  if (jingle.childNodes.length != 1) {
    return null;
  }
  var content = jingle.firstChild;
  if (content.nodeName != 'content') {
    return null;
  }
  var content_children = content.childNodes;
  var result = '';
  for (var c = 0; c < content_children.length; c++) {
    /** @type {Node} */
    var content_child = content_children[c];
    var cname = content_child.nodeName;
    if (cname == 'description') {
      var channels = '';
      var resolution = '';
      var auth = '';
      var desc_children = content_child.childNodes;
      for (var d = 0; d < desc_children.length; d++) {
        /** @type {Node} */
        var desc = desc_children[d];
        var dname = desc.nodeName;
        if (dname == 'control' || dname == 'event' || dname == 'video') {
          var channel_str = this.calcChannelString(desc);
          if (!channel_str) {
            return null;
          }
          channels += channel_str;
        } else if (dname == 'initial-resolution') {
          resolution = desc.getAttribute('width') + 'x' +
              desc.getAttribute('height');
        } else if (dname == 'authentication') {
          var auth_children = desc.childNodes;
          for (var a = 0; a < auth_children.length; a++) {
            /** @type {Node} */
            var auth_info = auth_children[a];
            if (auth_info.nodeName == 'auth-token') {
              auth = auth + ' (auth-token) ' + auth_info.textContent;
            } else if (auth_info.nodeName == 'certificate') {
              auth = auth + ' (certificate) ' + auth_info.textContent;
            } else if (auth_info.nodeName == 'master-key') {
              auth = auth + ' (master-key) ' + auth_info.textContent;
            } else {
              return null;
            }
          }
        } else {
          return null;
        }
      }
      result += '\n  channels: ' + channels;
      result += '\n  auth: ' + auth;
      result += '\n  initial resolution: ' + resolution;
    } else if (cname == 'transport') {
      // The 'transport' node is currently empty.
      var transport_children = content_child.childNodes;
      if (transport_children.length != 0) {
        return null;
      }
    } else {
      return null;
    }
  }
  return result;
};

/**
 * Pretty print the session-terminate info from the given Xml node.
 *
 * @param {Node} jingle Xml node with jingle session-terminate info contained in
 *                      child nodes.
 *
 * @return {?string} Pretty version of jingle session-terminate stanza. Null if
 *                  error.
 */
remoting.FormatIq.prototype.prettySessionTerminate = function(jingle) {
  if (jingle.childNodes.length != 1) {
    return null;
  }
  var reason = jingle.firstChild;
  if (reason.nodeName != 'reason' || reason.childNodes.length != 1) {
    return null;
  }
  var info = reason.firstChild;
  if (info.nodeName == 'success' || info.nodeName == 'general-error') {
    return '\n  reason=' + info.nodeName;
  }
  return null;
};

/**
 * Pretty print the transport-info info from the given Xml node.
 *
 * @param {Node} jingle Xml node with jingle transport info contained in child
 *                      nodes.
 *
 * @return {?string} Pretty version of jingle transport-info stanza. Null if
 *                  error.
 */
remoting.FormatIq.prototype.prettyTransportInfo = function(jingle) {
  if (jingle.childNodes.length != 1) {
    return null;
  }
  var content = jingle.firstChild;
  if (content.nodeName != 'content') {
    return null;
  }
  var transport = content.firstChild;
  if (transport.nodeName != 'transport') {
    return null;
  }
  var transport_children = transport.childNodes;
  var result = '';
  for (var t = 0; t < transport_children.length; t++) {
    /** @type {Node} */
    var candidate = transport_children[t];
    if (candidate.nodeName != 'candidate') {
      return null;
    }
    if (!this.verifyAttributes(candidate, 'name,address,port,preference,' +
                               'username,protocol,generation,password,type,' +
                               'network')) {
      return null;
    }
    var name = candidate.getAttribute('name');
    var address = candidate.getAttribute('address');
    var port = candidate.getAttribute('port');
    var pref = candidate.getAttribute('preference');
    var username = candidate.getAttribute('username');
    var protocol = candidate.getAttribute('protocol');
    var generation = candidate.getAttribute('generation');
    var password = candidate.getAttribute('password');
    var type = candidate.getAttribute('type');
    var network = candidate.getAttribute('network');

    var info = name + ': ' + address + ':' + port + ' ' + protocol +
        ' name:' + username + ' pwd:' + password +
        ' pref:' + pref +
        ' ' + type;
    if (network) {
      info = info + " network:'" + network + "'";
    }
    result += '\n  ' + info;
  }
  return result;
};

/**
 * Pretty print the jingle action contained in the given Xml node.
 *
 * @param {Node} jingle Xml node with jingle action contained in child nodes.
 * @param {string} action String containing the jingle action.
 *
 * @return {?string} Pretty version of jingle action stanze. Null if error.
 */
remoting.FormatIq.prototype.prettyJingleAction = function(jingle, action) {
  if (action == 'session-initiate' || action == 'session-accept') {
    return this.prettySessionInitiateAccept(jingle);
  }
  if (action == 'session-terminate') {
    return this.prettySessionTerminate(jingle);
  }
  if (action == 'transport-info') {
    return this.prettyTransportInfo(jingle);
  }
  return null;
};

/**
 * Pretty print the jingle error information contained in the given Xml node.
 *
 * @param {Node} error Xml node containing error information in child nodes.
 *
 * @return {?string} Pretty version of error stanze. Null if error.
 */
remoting.FormatIq.prototype.prettyError = function(error) {
  if (!this.verifyAttributes(error, 'xmlns:err,code,type,err:hostname,' +
                             'err:bnsname,err:stacktrace')) {
    return null;
  }
  var code = error.getAttribute('code');
  var type = error.getAttribute('type');
  var hostname = error.getAttribute('err:hostname');
  var bnsname = error.getAttribute('err:bnsname');
  var stacktrace = error.getAttribute('err:stacktrace');

  var result = '\n  error ' + code + ' ' + type + " hostname:'" +
             hostname + "' bnsname:'" + bnsname + "'";
  var children = error.childNodes;
  for (var i = 0; i < children.length; i++) {
    /** @type {Node} */
    var child = children[i];
    result += '\n  ' + child.nodeName;
  }
  if (stacktrace) {
    var stack = stacktrace.split(' | ');
    result += '\n  stacktrace:';
    // We use 'length-1' because the stack trace ends with " | " which results
    // in an empty string at the end after the split.
    for (var s = 0; s < stack.length - 1; s++) {
      result += '\n    ' + stack[s];
    }
  }
  return result;
};

/**
 * Print out the heading line for an iq node.
 *
 * @param {string} action String describing action (send/receive).
 * @param {string} id Packet id.
 * @param {string} desc Description of iq action for this node.
 * @param {string|null} sid Session id.
 *
 * @return {string} Pretty version of stanza heading info.
 */
remoting.FormatIq.prototype.prettyIqHeading = function(action, id, desc,
                                                       sid) {
  var message = 'iq ' + action + ' id=' + id;
  if (desc) {
    message = message + ' ' + desc;
  }
  if (sid) {
    message = message + ' sid=' + sid;
  }
  return message;
};

/**
 * Print out an iq 'result'-type node.
 *
 * @param {string} action String describing action (send/receive).
 * @param {NodeList} iq_list Node list containing the 'result' xml.
 *
 * @return {?string} Pretty version of Iq result stanza. Null if error.
 */
remoting.FormatIq.prototype.prettyIqResult = function(action, iq_list) {
  /** @type {Node} */
  var iq = iq_list[0];
  var id = iq.getAttribute('id');
  var iq_children = iq.childNodes;

  if (iq_children.length == 0) {
    return this.prettyIqHeading(action, id, 'result (empty)', null);
  } else if (iq_children.length == 1) {
    /** @type {Node} */
    var child = iq_children[0];
    if (child.nodeName == 'query') {
      if (!this.verifyAttributes(child, 'xmlns')) {
        return null;
      }
      var xmlns = child.getAttribute('xmlns');
      if (xmlns == 'google:jingleinfo') {
        var result = this.prettyIqHeading(action, id, 'result ' + xmlns, null);
        result += this.prettyJingleinfo(child);
        return result;
      }
      return '';
    } else if (child.nodeName == 'rem:log-result') {
      if (!this.verifyAttributes(child, 'xmlns:rem')) {
        return null;
      }
      return this.prettyIqHeading(action, id, 'result (log-result)', null);
    }
  }
  return null;
};

/**
 * Print out an Iq 'get'-type node.
 *
 * @param {string} action String describing action (send/receive).
 * @param {NodeList} iq_list Node containing the 'get' xml.
 *
 * @return {?string} Pretty version of Iq get stanza. Null if error.
 */
remoting.FormatIq.prototype.prettyIqGet = function(action, iq_list) {
  /** @type {Node} */
  var iq = iq_list[0];
  var id = iq.getAttribute('id');
  var iq_children = iq.childNodes;

  if (iq_children.length != 1) {
    return null;
  }

  /** @type {Node} */
  var query = iq_children[0];
  if (query.nodeName != 'query') {
    return null;
  }
  if (!this.verifyAttributes(query, 'xmlns')) {
    return null;
  }
  var xmlns = query.getAttribute('xmlns');
  return this.prettyIqHeading(action, id, 'get ' + xmlns, null);
};

/**
 * Print out an iq 'set'-type node.
 *
 * @param {string} action String describing action (send/receive).
 * @param {NodeList} iq_list Node containing the 'set' xml.
 *
 * @return {?string} Pretty version of Iq set stanza. Null if error.
 */
remoting.FormatIq.prototype.prettyIqSet = function(action, iq_list) {
  /** @type {Node} */
  var iq = iq_list[0];
  var id = iq.getAttribute('id');
  var iq_children = iq.childNodes;

  var children = iq_children.length;
  if (children == 1) {
    /** @type {Node} */
    var child = iq_children[0];
    if (child.nodeName == 'gr:log') {
      var grlog = child;
      if (!this.verifyAttributes(grlog, 'xmlns:gr')) {
        return null;
      }

      if (grlog.childNodes.length != 1) {
        return null;
      }
      var grentry = grlog.firstChild;
      if (grentry.nodeName != 'gr:entry') {
        return null;
      }
      if (!this.verifyAttributes(grentry, 'role,event-name,session-state,' +
                                 'os-name,cpu,browser-version,' +
                                 'webapp-version')) {
        return null;
      }
      var role = grentry.getAttribute('role');
      var event_name = grentry.getAttribute('event-name');
      var session_state = grentry.getAttribute('session-state');
      var os_name = grentry.getAttribute('os-name');
      var cpu = grentry.getAttribute('cpu');
      var browser_version = grentry.getAttribute('browser-version');
      var webapp_version = grentry.getAttribute('webapp-version');

      var result = this.prettyIqHeading(action, id, role + ' ' + event_name +
                                        ' ' + session_state, null);
      result += '\n  ' + os_name + ' ' + cpu + " browser:" + browser_version +
                     " webapp:" + webapp_version;
      return result;
    }
    if (child.nodeName == 'jingle') {
      var jingle = child;
      if (!this.verifyAttributes(jingle, 'xmlns,action,sid,initiator')) {
        return null;
      }

      var jingle_action = jingle.getAttribute('action');
      var sid = jingle.getAttribute('sid');

      var result = this.prettyIqHeading(action, id, 'set ' + jingle_action,
                                        sid);
      var action_str = this.prettyJingleAction(jingle, jingle_action);
      if (!action_str) {
        return null;
      }
      return result + action_str;
    }
  }
  return null;
};

/**
 * Print out an iq 'error'-type node.
 *
 * @param {string} action String describing action (send/receive).
 * @param {NodeList} iq_list Node containing the 'error' xml.
 *
 * @return {?string} Pretty version of iq error stanza. Null if error parsing
 *                  this stanza.
 */
remoting.FormatIq.prototype.prettyIqError = function(action, iq_list) {
  /** @type {Node} */
  var iq = iq_list[0];
  var id = iq.getAttribute('id');
  var iq_children = iq.childNodes;

  var children = iq_children.length;
  if (children != 2) {
    return null;
  }

  /** @type {Node} */
  var jingle = iq_children[0];
  if (jingle.nodeName != 'jingle') {
    return null;
  }
  if (!this.verifyAttributes(jingle, 'xmlns,action,sid,initiator')) {
    return null;
  }
  var jingle_action = jingle.getAttribute('action');
  var sid = jingle.getAttribute('sid');
  var result = this.prettyIqHeading(action, id, 'error from ' + jingle_action,
                                    sid);
  var action_str = this.prettyJingleAction(jingle, jingle_action);
  if (!action_str) {
    return null;
  }
  result += action_str;

  /** @type {Node} */
  var error = iq_children[1];
  if (error.nodeName != 'cli:error') {
    return null;
  }

  var error_str = this.prettyError(error);
  if (!error_str) {
    return null;
  }
  result += error_str;
  return result;
};

/**
 * Try to log a pretty-print the given IQ stanza (XML).
 * Return true if the stanza was successfully printed.
 *
 * @param {boolean} send True if we're sending this stanza; false for receiving.
 * @param {string} message The XML stanza to add to the log.
 *
 * @return {?string} Pretty version of the Iq stanza. Null if error.
 */
remoting.FormatIq.prototype.prettyIq = function(send, message) {
  var parser = new DOMParser();
  var xml = parser.parseFromString(message, 'text/xml');

  var iq_list = xml.getElementsByTagName('iq');

  if (iq_list && iq_list.length > 0) {
    /** @type {Node} */
    var iq = iq_list[0];
    if (!this.verifyAttributes(iq, 'xmlns,xmlns:cli,id,to,from,type'))
      return null;

    // Verify that the to/from fields match the expected sender/receiver.
    var to = iq.getAttribute('to');
    var from = iq.getAttribute('from');
    var action = '';
    var bot = remoting.settings.DIRECTORY_BOT_JID;
    if (send) {
      if (to && to != this.hostJid && to != bot) {
        console.warn('FormatIq: bad to: ' + to);
        return null;
      }
      if (from && from != this.clientJid) {
        console.warn('FormatIq: bad from: ' + from);
        return null;
      }

      action = "send";
      if (to == bot) {
        action = action + " (to bot)";
      }
    } else {
      if (to && to != this.clientJid) {
        console.warn('FormatIq: bad to: ' + to);
        return null;
      }
      if (from && from != this.hostJid && from != bot) {
        console.warn('FormatIq: bad from: ' + from);
        return null;
      }

      action = "receive";
      if (from == bot) {
        action = action + " (from bot)";
      }
    }

    var type = iq.getAttribute('type');
    if (type == 'result') {
      return this.prettyIqResult(action, iq_list);
    } else if (type == 'get') {
      return this.prettyIqGet(action, iq_list);
    } else if (type == 'set') {
      return this.prettyIqSet(action, iq_list);
    } else  if (type == 'error') {
      return this.prettyIqError(action, iq_list);
    }
  }

  return null;
};

/**
 * Return a pretty-formatted string for the IQ stanza being sent.
 * If the stanza cannot be made pretty, then a string with a raw dump of the
 * stanza will be returned.
 *
 * @param {string} message The XML stanza to make pretty.
 *
 * @return {string} Pretty version of XML stanza being sent. A raw dump of the
 *                  stanza is returned if there was a parsing error.
 */
remoting.FormatIq.prototype.prettifySendIq = function(message) {
  var result = this.prettyIq(true, message);
  if (!result) {
    // Fall back to showing the raw stanza.
    return 'Sending Iq: ' + message;
  }
  return result;
};

/**
 * Return a pretty-formatted string for the IQ stanza that was received.
 * If the stanza cannot be made pretty, then a string with a raw dump of the
 * stanza will be returned.
 *
 * @param {string} message The XML stanza to make pretty.
 *
 * @return {string} Pretty version of XML stanza that was received. A raw dump
 *                  of the stanza is returned if there was a parsing error.
 */
remoting.FormatIq.prototype.prettifyReceiveIq = function(message) {
  var result = this.prettyIq(false, message);
  if (!result) {
    // Fall back to showing the raw stanza.
    return 'Receiving Iq: ' + message;
  }
  return result;
};

/** @type {remoting.FormatIq} */
remoting.formatIq = null;
