/*
 *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import java.util.Map;

/**
 * Java version of webrtc::RTCStats. Represents an RTCStats object, as
 * described in https://w3c.github.io/webrtc-stats/. The |id|, |timestampUs|
 * and |type| accessors have the same meaning for this class as for the
 * RTCStats dictionary. Each RTCStatsReport produced by getStats contains
 * multiple RTCStats objects; one for each underlying object (codec, stream,
 * transport, etc.) that was inspected to produce the stats.
 */
public class RTCStats {
  private final long timestampUs;
  private final String type;
  private final String id;
  private final Map<String, Object> members;

  public RTCStats(long timestampUs, String type, String id, Map<String, Object> members) {
    this.timestampUs = timestampUs;
    this.type = type;
    this.id = id;
    this.members = members;
  }

  // Timestamp in microseconds.
  public double getTimestampUs() {
    return timestampUs;
  }

  // Equivalent to RTCStatsType in the stats spec. Indicates the type of the
  // object that was inspected to produce the stats.
  public String getType() {
    return type;
  }

  // Unique ID representing this stats object. May be referred to by members of
  // other stats objects.
  public String getId() {
    return id;
  }

  /**
   * Returns map of member names to values. Returns as an ordered map so that
   * the stats object can be serialized with a consistent ordering.
   *
   * Values will be one of the following objects:
   * - Boolean
   * - Integer (for 32-bit signed integers)
   * - Long (for 32-bit unsigned and 64-bit signed integers)
   * - BigInteger (for 64-bit unsigned integers)
   * - Double
   * - String
   * - The array form of any of the above (e.g., Integer[])
   */
  public Map<String, Object> getMembers() {
    return members;
  }

  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("{ timestampUs: ")
        .append(timestampUs)
        .append(", type: ")
        .append(type)
        .append(", id: ")
        .append(id);
    boolean first = true;
    for (Map.Entry<String, Object> entry : members.entrySet()) {
      builder.append(", ").append(entry.getKey()).append(": ");
      appendValue(builder, entry.getValue());
    }
    builder.append(" }");
    return builder.toString();
  }

  private static void appendValue(StringBuilder builder, Object value) {
    if (value instanceof Object[]) {
      Object[] arrayValue = (Object[]) value;
      builder.append('[');
      for (int i = 0; i < arrayValue.length; ++i) {
        if (i != 0) {
          builder.append(", ");
        }
        appendValue(builder, arrayValue[i]);
      }
      builder.append(']');
    } else if (value instanceof String) {
      // Enclose strings in quotes to make it clear they're strings.
      builder.append('"').append(value).append('"');
    } else {
      builder.append(value);
    }
  }
}
