<!--
  This in an HTML Import-able file that contains the definition
  of the following elements:

    <job-timeline-sk>

  Status information about the task scheduler.

  To use this file import it:

    <link href="/res/imp/job-timeline-sk.html" rel="import" />

  Usage:

    <job-timeline-sk job="[[job]]" tasks="[[tasks]]" epochs="[[epochs]]"></job-timeline-sk>

  Properties:
    job: Job instance, as provided by the Task Scheduler server.
    tasks: Array of Task instances, as provided by the Task Scheduler server.
    epochs: Array of Strings; timestamps indicating events, eg. scheduler tick times.

  Methods:
    None.

  Events:
    None.
-->
<link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
<dom-module id="job-timeline-sk">
  <template>
    <style>
    :host{
      flex-grow: 1;
      display: flex;
      flex-direction: column;
    }
    #svg {
      flex-grow: 1;
      min-width: 600px;
      min-height: 300px;
      max-width: 1800px;
      max-height: 800px;
    }
    </style>
    <h2>Job <span>[[job.id]]</span></h2>
    <div class="layout horizontal"><a href$="/job/[[job.id]]">[back to job page]</a></div>
    <svg id="svg"></svg>
  </template>
  <script src="/res/imp/bower_components/d3/d3.min.js"></script>
  <script src="/res/js/gantt.js"></script>
  <script>
  (function() {
    function ts(tsStr) {
      // If the timestamp is zero-ish, return the current datetime.
      if (Date.parse(tsStr) <= 0) {
        return new Date();
      }
      return new Date(tsStr);
    }

    Polymer({
      is: "job-timeline-sk",

      properties: {
        job: {
          type: Object,
        },
        tasks: {
          type: Array,
        },
        epochs: {
          type: Array,
        },
        _chart: {
          type: Object,
        },
      },

      observers: [
        "_draw(job.*, tasks.*, epochs.*)",
      ],

      attached: function() {
        this._chart = gantt(this.$.svg);
        window.addEventListener("resize", this.draw.bind(this));
        this.draw();
      },

      draw: function() {
        this.debounce("draw", function() {
          this._draw();
        }.bind(this));
      },

      _draw: function() {
        if (!this.job || !this.tasks || this.epochs === undefined || !this._chart) {
          return;
        }
        const tasks = [{
          category: this.job.name + " (job)",
          start: ts(this.job.created),
          end: ts(this.job.finished),
          color: "#0072b2",
        }];
        for (const t of this.tasks) {
          // Creation timestamp may be after start and finish timestamps in the
          // case of deduplicated tasks. Since we care more about the
          // contribution to the job than the task itself, set the start and
          // finish timestamps equal to the creation timestamp in this case.
          const createTs = ts(t.created);
          if (t.started && ts(t.started).getTime() < createTs.getTime()) {
            t.started = t.created;
          }
          if (t.finished && ts(t.finished).getTime() < createTs.getTime()) {
            t.finished = t.created;
          }

          const segments = [];
          let lastSegmentEnd = createTs;
          const seg = function(label, end, color) {
            const s = {
              label: label,
              start: lastSegmentEnd,
              end: ts(end),
              color: color,
            };
            lastSegmentEnd = s.end;
            segments.push(s);
          };
          if (t.started) {
            seg("pending", t.started, "#e69f00");
          }
          if (t.swarming && t.swarming.performance_stats && t.swarming.performance_stats.isolated_upload) {
            const overheadTotal = t.swarming.performance_stats.bot_overhead * 1000;
            const overheadUpload = t.swarming.performance_stats.isolated_upload.duration * 1000;
            const overheadDownload = overheadTotal - overheadUpload;
            const startTs = ts(t.started).getTime();
            const finishTs = ts(t.finished).getTime();
            seg("overhead", startTs + overheadDownload, "#d55e00");
            seg("running", finishTs - overheadUpload, "#0072b2");
            seg("overhead", t.finished, "#d55e00");
          } else {
            seg("running", t.finished, "#0072b2");
          }
          tasks.push({
            category: t.name,
            start: ts(t.created),
            end: ts(t.finished),
            segments: segments,
          });
        }
        const epochs = [];
        for (const epoch of this.epochs) {
          epochs.push(ts(epoch));
        }
        let g = this._chart.tasks(tasks).epochs(epochs);
        if (this.job.requested) {
          g.start(ts(this.job.requested));
        }
        g.draw();
      }
    });
  })();
  </script>
</dom-module>
