// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * @fileoverview Utilities to debug JSPB based proto objects.
 */

goog.provide('jspb.debug');

goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.object');
goog.require('jspb.Message');


/**
 * Turns a proto into a human readable object that can i.e. be written to the
 * console: `console.log(jspb.debug.dump(myProto))`.
 * This function makes a best effort and may not work in all cases. It will not
 * work in obfuscated and or optimized code.
 * Use this in environments where {@see jspb.Message.prototype.toObject} is
 * not available for code size reasons.
 * @param {jspb.Message} message A jspb.Message.
 * @return {Object}
 */
jspb.debug.dump = function(message) {
  if (!goog.DEBUG) {
    return null;
  }
  goog.asserts.assert(message instanceof jspb.Message,
      'jspb.Message instance expected');
  /** @type {Object} */
  var object = message;
  goog.asserts.assert(object['getExtension'],
      'Only unobfuscated and unoptimized compilation modes supported.');
  return /** @type {Object} */ (jspb.debug.dump_(message));
};


/**
 * Recursively introspects a message and the values its getters return to
 * make a best effort in creating a human readable representation of the
 * message.
 * @param {?} thing A jspb.Message, Array or primitive type to dump.
 * @return {*}
 * @private
 */
jspb.debug.dump_ = function(thing) {
  var type = goog.typeOf(thing);
  var message = thing;  // Copy because we don't want type inference on thing.
  if (type == 'number' || type == 'string' || type == 'boolean' ||
      type == 'null' || type == 'undefined') {
    return thing;
  }
  if (typeof Uint8Array !== 'undefined') {
    // Will fail on IE9, where Uint8Array doesn't exist.
    if (message instanceof Uint8Array) {
      return thing;
    }
  }

  if (type == 'array') {
    goog.asserts.assertArray(thing);
    return goog.array.map(thing, jspb.debug.dump_);
  }
  goog.asserts.assert(message instanceof jspb.Message,
      'Only messages expected: ' + thing);
  var ctor = message.constructor;
  var messageName = ctor.name || ctor.displayName;
  var object = {
    '$name': messageName
  };
  for (var name in ctor.prototype) {
    var match = /^get([A-Z]\w*)/.exec(name);
    if (match && name != 'getExtension' &&
        name != 'getJsPbMessageId') {
      var has = 'has' + match[1];
      if (!thing[has] || thing[has]()) {
        var val = thing[name]();
        object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val);
      }
    }
  }
  if (COMPILED && thing['extensionObject_']) {
    object['$extensions'] = 'Recursive dumping of extensions not supported ' +
        'in compiled code. Switch to uncompiled or dump extension object ' +
        'directly';
    return object;
  }
  var extensionsObject;
  for (var id in ctor['extensions']) {
    if (/^\d+$/.test(id)) {
      var ext = ctor['extensions'][id];
      var extVal = thing.getExtension(ext);
      var fieldName = goog.object.getKeys(ext.fieldName)[0];
      if (extVal != null) {
        if (!extensionsObject) {
          extensionsObject = object['$extensions'] = {};
        }
        extensionsObject[jspb.debug.formatFieldName_(fieldName)] =
            jspb.debug.dump_(extVal);
      }
    }
  }
  return object;
};


/**
 * Formats a field name for output as camelCase.
 *
 * @param {string} name Name of the field.
 * @return {string}
 * @private
 */
jspb.debug.formatFieldName_ = function(name) {
  // Name may be in TitleCase.
  return name.replace(/^[A-Z]/, function(c) {
    return c.toLowerCase();
  });
};
