/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 htrace = htrace || {};

// The invalid span ID, which is all zeroes.
htrace.INVALID_SPAN_ID = "00000000000000000000000000000000";

// Convert an array of htrace.Span models into a comma-separated string.
htrace.spanModelsToString = function(spans) {
  var ret = "";
  var prefix = "";
  for (var i = 0; i < spans.length; i++) {
    ret += prefix + JSON.stringify(spans[i].unparse());
    prefix = ", ";
  }
  return ret;
};

// Convert an array of return results from ajax calls into an array of
// htrace.Span models.
htrace.parseMultiSpanAjaxQueryResults = function(ajaxCalls) {
  var parsedSpans = [];
  for (var i = 0; i < ajaxCalls.length; i++) {
    var text = ajaxCalls[i][0];
    var result = ajaxCalls[i][1];
    if (ajaxCalls[i]["status"] != "200") {
      throw "ajax error: " + ajaxCalls[i].statusText;
    }
    var parsedSpan = new htrace.Span({});
    try {
      parsedSpan.parse(ajaxCalls[i].responseJSON, {});
    } catch (e) {
      throw "span parse error: " + e;
    }
    parsedSpans.push(parsedSpan);
  }
  return parsedSpans;
};

htrace.sortSpansByBeginTime = function(spans) {
  return spans.sort(function(a, b) {
      if (a.get("begin") < b.get("begin")) {
        return -1;
      } else if (a.get("begin") > b.get("begin")) {
        return 1;
      } else {
        return 0;
      }
    });
};

htrace.getReifiedParents = function(span) {
  return span.get("reifiedParents") || [];
};

htrace.getReifiedChildren = function(span) {
  return span.get("reifiedChildren") || [];
};

htrace.Span = Backbone.Model.extend({
  // Parse a span sent from htraced.
  // We use more verbose names for some attributes.
  // Missing attributes are treated as zero or empty.  Numerical attributes are
  // forced to be numbers.
  parse: function(response, options) {
    var span = {};
    this.set("spanId", response.a ? response.a : htrace.INVALID_SPAN_ID);
    this.set("tracerId", response.r ? response.r : "");
    this.set("parents", response.p ? response.p : []);
    this.set("description", response.d ? response.d : "");
    this.set("begin", response.b ? parseInt(response.b, 10) : 0);
    this.set("end", response.e ? parseInt(response.e, 10) : 0);
    if (response.t) {
      var t = response.t.sort(function(a, b) {
          if (a.t < b.t) {
            return -1;
          } else if (a.t > b.t) {
            return 1;
          } else {
            return 0;
          }
        });
      this.set("timeAnnotations", t);
    } else {
      this.set("timeAnnotations", []);
    }
    this.set("infoAnnotations", response.n ? response.n : {});
    this.set("selected", false);

    // reifiedChildren starts off as null and will be filled in as needed.
    this.set("reifiedChildren", null);

    // If there are parents, reifiedParents starts off as null.  Otherwise, we
    // know it is the empty array.
    this.set("reifiedParents", (this.get("parents").length == 0) ? [] : null);

    return span;
  },

  // Transform a span model back into a JSON string suitable for sending over
  // the wire.
  unparse: function() {
    var obj = { };
    if (!(this.get("spanId") === htrace.INVALID_SPAN_ID)) {
      obj.a = this.get("spanId");
    }
    if (!(this.get("tracerId") === "")) {
      obj.r = this.get("tracerId");
    }
    if (this.get("parents").length > 0) {
      obj.p = this.get("parents");
    }
    if (this.get("description").length > 0) {
      obj.d = this.get("description");
    }
    if (this.get("begin") > 0) {
      obj.b = this.get("begin");
    }
    if (this.get("end") > 0) {
      obj.e = this.get("end");
    }
    if (this.get("timeAnnotations").length > 0) {
      obj.t = this.get("timeAnnotations");
    }
    if (_.size(this.get("infoAnnotations")) > 0) {
      obj.n = this.get("infoAnnotations");
    }
    return obj;
  },

  reifyParentsRecursive: function(depth) {
    var rootDeferred = jQuery.Deferred();
    var span = this;
    span.reifyParents().done(function(err) {
      if ((err != "") || (depth <= 0)) {
        rootDeferred.resolve(err);
        return;
      }
      var recursivePromises = [];
      var reifiedParents = span.get("reifiedParents");
      for (var j = 0; j < reifiedParents.length; j++) {
        recursivePromises.push(reifiedParents[j].reifyParentsRecursive(depth - 1));
      }
      $.when.apply($, recursivePromises).then(function() {
        for (var i = 0; i < arguments.length; i++) {
          if (arguments[i] != "") {
            rootDeferred.resolve(arguments[i]);
            return;
          }
        }
        rootDeferred.resolve("");
      });
    });
    return rootDeferred.promise();
  },

  //
  // Although the parent IDs are always present in the 'parents' field of the
  // span, sometimes we need the actual parent span models.  In that case we
  // must "reify" them (make them real).
  //
  // This functionReturns a jquery promise which reifies all the parents of this
  // span and stores them into reifiedParents.  The promise returns the empty
  // string on success, or an error string on failure.
  //
  reifyParents: function() {
    var span = this;
    var numParents = span.get("parents").length;
    var ajaxCalls = [];
    // Set up AJAX queries to reify the parents.
    for (var i = 0; i < numParents; i++) {
      ajaxCalls.push($.ajax({
        url: "span/" + span.get("parents")[i],
        data: {},
        contentType: "application/json; charset=utf-8",
        dataType: "json"
      }));
    }
    var rootDeferred = jQuery.Deferred();
    $.when.apply($, ajaxCalls).then(function() {
      var reifiedParents = [];
      try {
        reifiedParents = htrace.parseMultiSpanAjaxQueryResults(ajaxCalls);
      } catch (e) {
        rootDeferred.resolve("Error reifying parents for " +
            span.get("spanId") + ": " + e);
        return;
      }
      reifiedParents = htrace.sortSpansByBeginTime(reifiedParents);
      // The current span is a child of the reified parents.  There may be other
      // children of those parents, but we are ignoring that here.  By making
      // this non-null, the "expand children" button will not appear for these
      // paren spans.
      for (var j = 0; j < reifiedParents.length; j++) {
        reifiedParents[j].set("reifiedChildren", [span]);
      }
      console.log("Setting reified parents for " + span.get("spanId") +
          " to " + htrace.spanModelsToString (reifiedParents));
      span.set("reifiedParents", reifiedParents);
      rootDeferred.resolve("");
    });
    return rootDeferred.promise();
  },

  reifyChildrenRecursive: function(depth) {
    var rootDeferred = jQuery.Deferred();
    var span = this;
    span.reifyChildren().done(function(err) {
      if ((err != "") || (depth <= 0)) {
        rootDeferred.resolve(err);
        return;
      }
      var recursivePromises = [];
      var reifiedChildren = span.get("reifiedChildren");
      for (var j = 0; j < reifiedChildren.length; j++) {
        recursivePromises.push(reifiedChildren[j].reifyChildrenRecursive(depth - 1));
      }
      $.when.apply($, recursivePromises).then(function() {
        for (var i = 0; i < arguments.length; i++) {
          if (arguments[i] != "") {
            rootDeferred.resolve(arguments[i]);
            return;
          }
        }
        rootDeferred.resolve("");
      });
    });
    return rootDeferred.promise();
  },

  //
  // The span itself does not contain its children.  However, the server has an
  // index which can be used to easily find the children of a particular span.
  //
  // This function returns a jquery promise which reifies all the children of
  // this span and stores them into reifiedChildren.  The promise returns the
  // empty string on success, or an error string on failure.
  //
  reifyChildren: function() {
    var rootDeferred = jQuery.Deferred();
    var span = this;
    $.ajax({
        url: "span/" + span.get("spanId") + "/children?lim=50",
        data: {},
        contentType: "application/json; charset=utf-8",
        dataType: "json"
      }).done(function(childIds) {
        var ajaxCalls = [];
        for (var i = 0; i < childIds.length; i++) {
          ajaxCalls.push($.ajax({
            url: "span/" + childIds[i],
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json"
          }));
        };
        $.when.apply($, ajaxCalls).then(function() {
          var reifiedChildren;
          try {
            reifiedChildren = htrace.parseMultiSpanAjaxQueryResults(ajaxCalls);
          } catch (e) {
            reifiedChildren = rootDeferred.resolve("Error reifying children " +
                "for " + span.get("spanId") + ": " + e);
            return;
          }
          reifiedChildren = htrace.sortSpansByBeginTime(reifiedChildren);
          // The current span is a parent of the new child.
          // There may be other parents, but we are ignoring that here.
          // By making this non-null, the "expand parents" button will not
          // appear for these child spans.
          for (var j = 0; j < reifiedChildren.length; j++) {
            reifiedChildren[j].set("reifiedParents", [span]);
          }
          console.log("Setting reified children for " + span.get("spanId") +
              " to " + htrace.spanModelsToString (reifiedChildren));
          span.set("reifiedChildren", reifiedChildren);
          rootDeferred.resolve("");
        });
      }).fail(function(statusData) {
        // Check if the /children query failed.
        rootDeferred.resolve("Error querying children of " +
            span.get("spanId") + ": got " + statusData);
        return;
      });
    return rootDeferred.promise();
  },

  // Get the earliest begin time of this span or any of its reified parents or
  // children.
  getEarliestBegin: function() {
    var earliestBegin = this.get("begin");
    htrace.treeTraverseDepthFirstPre(this, htrace.getReifiedParents, 0,
        function(span, depth) {
          earliestBegin = Math.min(earliestBegin, span.get("begin"));
        });
    htrace.treeTraverseDepthFirstPre(this, htrace.getReifiedChildren, 0,
        function(span, depth) {
          earliestBegin = Math.min(earliestBegin, span.get("begin"));
        });
    return earliestBegin;
  },

  // Get the earliest begin time of this span or any of its reified parents or
  // children.
  getLatestEnd: function() {
    var latestEnd = this.get("end");
    htrace.treeTraverseDepthFirstPre(this, htrace.getReifiedParents, 0,
        function(span, depth) {
          latestEnd = Math.max(latestEnd, span.get("end"));
        });
    htrace.treeTraverseDepthFirstPre(this, htrace.getReifiedChildren, 0,
        function(span, depth) {
          latestEnd = Math.max(latestEnd, span.get("end"));
        });
    return latestEnd;
  },
});
