<!--
  The res/js/status.js file must be included before this file.

  This in an HTML Import-able file this contains the definition
  of the following elements:

    <commits-data-sk>

  This element performs an ajax request to the status backend, parses the json response and
  returns bindable properties to be used to render the various components of the status page.
  This element takes some filter inputs (i.e. filter and search) and if
  either changes, the data will be re-filtered to reflect that.

  To use this file import it:

    <link href="/res/imp/commits-data-sk.html" rel="import" />

  Usage:

    <commits-data-sk></commits-data-sk>

  Properties:
    // inputs
    roll_statuses: Array, Status information about the autorollers, as defined in autoroll-widget-sk.html.
    commits_to_load: Number, the number of commits to load from the backend
    filter: String, the task spec filter to be used.
    reload: How often (in seconds) to reload the data.
    search: String, the string to be used if filter is "search".

    // outputs
    branch_heads: Array<Object>, an array of hashes and branch names of the commits.
    task_details: Object, a map of commit hash to an object that has the task results by task spec.
    task_specs: Object, a map of the task spec names to an object that has, among other things, category, subcategory, comments and master.
    tasks: Object, a map of the task spec names to an object that maps task IDs to task results.
    categories: Object, a map of the task spec categories to an object that has the subcategories and the colspan (total number of included task specs).
    category_list: Array<String>, an array of the task spec category names.
    commits: Array<Object>, the commit objects, in chronological order.
    commits_map: Object, a map of commit hash to commit objects.
    loading: Boolean, if the data is being fetched from the server or parsed.
    relanded_map: Object, a map of a commit hash that was relanded to the commit object that relands it
    reverted_map: Object, a map of a commit hash that was reverted to the commit object that reverts it
    swarming_url: String, the URL of the Swarming server.
    task_scheduler_url: String, the URL of the Task Scheduler.

  Methods:
    forceUpdate: Force the commits-data-sk to reload its data from the server.
    forceReProcess: Force the commits-data-sk to re-evaluate its data. Useful for
        when Polymer does not automatically trigger updates, eg. for complex objects.

  Events:
    None.
-->

<link rel="import" href="/res/imp/bower_components/iron-ajax/iron-ajax.html">

<link rel="import" href="/res/common/imp/timer-sk.html">

<dom-module id="commits-data-sk">
  <template>
    <timer-sk period="[[reload]]" on-trigger="_startUpdate"></timer-sk>
  </template>

  <script>
    (function() {
    var VALID_TASK_SPEC_CATEGORIES = ["Build", "Housekeeper", "Infra", "Perf", "Test", "Upload"];

    var FILTER_ALL = "all";
    var FILTER_DEFAULT = "default";
    var FILTER_INTERESTING = "interesting";
    var FILTER_FAILURES = "failures";
    var FILTER_FAIL_NO_COMMENT = "nocomment";
    var FILTER_COMMENTS = "comments";
    var FILTER_SEARCH = "search";

    var TASK_STATUS_PENDING = "";
    var TASK_STATUS_RUNNING = "RUNNING";
    var TASK_STATUS_SUCCESS = "SUCCESS";
    var TASK_STATUS_FAILURE = "FAILURE";
    var TASK_STATUS_MISHAP = "MISHAP";

    var TIME_POINTS = [
    {
      label:"-1h",
      offset: 60 * 60 * 1000,
    },
    {
      label:"-3h",
      offset: 3 * 60 * 60 * 1000,
    },
    {
      label:"-1d",
      offset: 24* 60 * 60 * 1000,
    },
    ];

    // shortCommit returns the first 7 characters of a commit hash.
    function shortCommit(commit) {
      return commit.substring(0, 7);
    }

    // shortAuthor shortens the commit author field by returning the
    // parenthesized email address if it exists. If it does not exist, the
    // entire author field is used.
    function shortAuthor(author) {
      var re = /.*\((.+)\)/;
      var match = re.exec(author);
      var res = author;
      if (match) {
        res = match[1];
      }
      return res.split("@")[0];
    }

    // shortSubject truncates a commit subject line to 72 characters if needed.
    // If the text was shortened, the last three characters are replaced by
    // ellipsis.
    function shortSubject(subject) {
      return sk.truncate(subject, 72);
    }

    // findIssueAndReviewTool returns an object literal of the form
    // {issue, patchStorage}. patchStorage will be either Gerrit or empty, and
    // issue will be the CL number or empty.
    // If an issue cannot be determined then an empty string is returned for
    // both issue and patchStorage.
    function findIssueAndReviewTool(commit) {
      // See if it is a Gerrit CL.
      var gerritRE = /(.|[\r\n])*Reviewed-on:.*\/([0-9]*)/g;
      var gerritTokens = gerritRE.exec(commit.body);
      if (gerritTokens) {
        return {
            issue: gerritTokens[gerritTokens.length - 1],
            patchStorage: 'gerrit'
        };
      }
      // Could not find a CL number return an empty string.
      return {
          issue: '',
          patchStorage: ''
      };
    }

    function isGerritIssue(commit) {
      return commit.patchStorage === 'gerrit';
    }

    // Find and return the commit which was reverted by the given commit.
    function findRevertedCommit(commits, commit) {
      patt = new RegExp("^This reverts commit ([a-f0-9]+)");
      var tokens = patt.exec(commit.body);
      if (tokens) {
        return commits[tokens[tokens.length - 1]];
      }
      return null;
    }

    // Find and return the commit which was relanded by the given commit.
    function findRelandedCommit(commits, commit) {
      // Relands can take one of two formats. The first is a "direct" reland.
      patt = new RegExp("^This is a reland of ([a-f0-9]+)");
      var tokens = patt.exec(commit.body);
      if (tokens) {
        return commits[tokens[tokens.length - 1]];
      }

      // The second is a revert of a revert.
      var revert = findRevertedCommit(commits, commit);
      if (revert) {
        return findRevertedCommit(commits, revert);
      }
      return null;
    }

    function getTaskColorClass(task) {
      // These styles are from the styles-sk module.
      if (task.status == TASK_STATUS_PENDING || task.status == TASK_STATUS_RUNNING) {
        return "bg-inprogress";
      } else if (task.status == TASK_STATUS_SUCCESS) {
        return "bg-success";
      } else if (task.status == TASK_STATUS_FAILURE) {
        return "bg-failure";
      } else if (task.status == TASK_STATUS_MISHAP) {
        return "bg-exception";
      }
      console.log("Unknown color for task "+task);
      return "bg-inprogress";
    }

    Polymer({
      is: "commits-data-sk",
      properties: {
        // input only
        roll_statuses: {
          type: Array,
          value: function() {
            return [];
          },
        },
        commits_to_load: {
          type: Number,
          value: 35,
          observer: "_reloadFromScratch",
        },
        filter: {
          type: String,
          observer:"_filterTaskSpecs",
        },
        is_sheriff: {
          type: Boolean,
        },
        is_trooper: {
          type: Boolean,
        },
        reload: {
          type: Number,
          value: 60,
        },
        repo: {
          type: String,
          observer: "_reloadFromScratch",
        },
        search: {
          type: String,
          observer: "_searchChanged",
        },

        // output only
        branch_heads: {
          type: Array,
          value: function() {
            return [];
          },
          notify:true,
        },
        task_details: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        tasks: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        task_specs: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        categories: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        category_list: {
          type: Array,
          value: function() {
            return [];
          },
          notify:true,
        },
        commits: {
          type: Array,
          notify:true,
        },
        commits_map: {
          type: Object,
          notify:true,
        },
        loading: {
          type: Number,
          notify: true,
          computed: "_or(_activeAJAX, _filtering)",
        },
        purple_tasks: {
          type: Array,
          notify: true,
        },
        relanded_map: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        reverted_map: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },
        swarming_url: {
          type: String,
          notify: true,
        },
        task_scheduler_url: {
          type: String,
          notify: true,
        },
        time_points: {
          type: Object,
          value: function() {
            return {};
          },
          notify:true,
        },

        //private
        _activeAJAX: {
          type: Boolean,
          value: false,
        },
        _filtering: {
          type: Boolean,
          value: false,
        },
        _data: {
          type: Object,
          value: function() {
            return {
              branch_heads: [],
              commitComments: {},
              commits: [],
              tasks: {},
              tasksByCommit: {},
              taskComments: {},
              tasks: {},
              taskSpecComments: {},
            };
          },
          observer:"",
        },
        _last_load_ts: {
          type: Number,
          value: 0,
        },
        _server_pod_id: {
          type: String,
          value: "",
        },
        _updateRequested: {
          type: Boolean,
          value: false,
        },
        _updateFromScratch: {
          type: Boolean,
          value: false,
        },
      },

      observers: [
        "_processData(_data.*, roll_statuses.*)",
      ],

      _or: function(a,b) {
        return a || b;
      },

      _makeCommitsMap: function(arr) {
        if (!arr || arr.length == 0) {
          this.set("commits_map", {});
          return;
        }
        var m = {};
        arr.forEach(function(c){
          m[c.hash] = c;
        });
        this.set("commits_map", m);
      },

      _clearData: function() {
        this._data = {
          branch_heads: [],
          commitComments: {},
          commits: [],
          taskComments: {},
          tasks: {},
          tasksByCommit: {},
          taskSpecComments: {},
        };
      },

      _reloadFromScratch: function() {
        this._startUpdate(true);
      },

      _startUpdate: function(fromScratch) {
        console.log("_startUpdate(" + fromScratch + ")");
        if (this._activeAJAX) {
          this._updateRequested = true;
          if (fromScratch === true) {
            this._updateFromScratch = true;
          }
          return;
        }
        this.set("_activeAJAX", true);
        this._update(fromScratch === true);
      },

      _updateFinished: function() {
        console.log("_updateFinished");
        if (this._updateRequested) {
          var fromScratch = this._updateFromScratch;
          this._updateRequested = false;
          this._updateFromScratch = false;
          this._update(fromScratch);
        } else {
          this._updateRequested = false;
          this._updateFromScratch = false;
          this.set("_activeAJAX", false);
        }
      },

      _update: function(fromScratch) {
        console.log("_update("+ fromScratch + ")");
        // Sanity check.
        if (!this._activeAJAX) {
          throw "Cannot call _update directly; must use _startUpdate!";
        }
        if (!this.repo || !this.commits_to_load) {
          this._updateFinished();
          return;
        }
        var ts = Date.now();
        var url = "/json/" + this.repo + "/incremental?n=" + this.commits_to_load;
        if (this._last_load_ts && !fromScratch) {
          url += "&from=" + this._last_load_ts;
        }
        if (this._server_pod_id) {
          url += "&pod=" + this._server_pod_id;
        }
        sk.get(url).then(JSON.parse).then(function(json) {
          // Clear out the existing data if necessary.
          if (json.start_over || fromScratch) {
            this._clearData();
          }

          // Keep track of the server pod ID. This ensures that we're in sync
          // with the server.
          this._server_pod_id = json.pod;

          // Mix the new data into the existing.
          if (!json.commits) {
            json.commits = [];
          }
          var sliceIdx = this._data.commits.length - json.commits.length;
          var keep = this._data.commits.slice(0, sliceIdx);
          var remove = this._data.commits.slice(sliceIdx, this._data.commits.length);
          this._data.commits = json.commits.concat(keep);

          // Replace the branch heads if they've changed.
          if (json.branch_heads) {
            this._data.branch_heads = json.branch_heads;
          }

          // Add new tasks, replace modified ones.
          if (json.tasks) {
            for (var i = 0; i < json.tasks.length; i++) {
              var task = json.tasks[i];
              this._data.tasks[task.id] = task;
            }
          }

          // Remove too-old tasks.
          for (var i = 0; i < remove.length; i++) {
            var commit = remove[i];
            for (var id in this._data.tasks) {
              if (this._data.tasks[id].revision == commit) {
                delete this._data.tasks[id];
              }
            }
          }

          // Map commits to tasks.
          for (var id in this._data.tasks) {
            var task = this._data.tasks[id];
            if (task.commits) {
              for (var j = 0; j < task.commits.length; j++) {
                var commit = task.commits[j];
                var tasksForCommit = this._data.tasksByCommit[commit];
                if (!tasksForCommit) {
                  tasksForCommit = {};
                  this._data.tasksByCommit[commit] = tasksForCommit;
                }
                tasksForCommit[task.name] = task;
              }
            }
          }

          if (json.swarming_url) {
            this.set("swarming_url", json.swarming_url);
          }
          if (json.task_scheduler_url) {
            this.set("task_scheduler_url", json.task_scheduler_url);
          }
          if (json.commit_comments) {
            this._data.commitComments = json.commit_comments;
          }
          if (json.task_comments) {
            this._data.taskComments = json.task_comments;
          }
          if (json.task_spec_comments) {
            this._data.taskSpecComments = json.task_spec_comments;
          }

          // Update the last-load timestamp.
          this._last_load_ts = ts;
          this._updateFinished();
          this._processData(this._data);
        }.bind(this)).catch(function(msg) {
          this._updateFinished();
          sk.errorMessage("Failed to load new data: " + msg);
        }.bind(this));
      },

      _processData: function(data) {
        if (!data || !data.commits || data.commits.length == 0) {
          return;
        }
        this.set("_filtering", true);
        console.time("_processData");
        for (var i = 0; i < data.commits.length; i++) {
          data.commits[i].comments = data.commitComments[data.commits[i].hash] || [];
        }

        var commits = data.commits;
        var commitsMap = {};
        for (var i = 0; i < commits.length; i++) {
          commitsMap[commits[i].hash] = commits[i];
        }

        // Prepare task data.
        var tasks = {};
        var task_specs = {};
        var task_details = this.task_details;
        for (var commit in data.tasksByCommit) {
          task_details[commit] = data.tasksByCommit[commit];
          for (var taskSpec in task_details[commit]) {
            var task = task_details[commit][taskSpec];
            task.comments = [];
            if (data.taskComments[commit] && data.taskComments[commit][taskSpec]) {
              task.comments = data.taskComments[commit][taskSpec];
            }
          }
        }

        for (var i = 0; i < commits.length; i++) {
          var commit = commits[i];
          commit.shortAuthor = shortAuthor(commit.author);
          commit.shortHash = shortCommit(commit.hash);
          commit.shortSubject = shortSubject(commit.subject);

          var c = findIssueAndReviewTool(commit);
          commit.issue = c.issue;
          commit.patchStorage = c.patchStorage;
        }

        for (var i = 0; i < commits.length; i++) {
          var commit = commits[i];
          commit.isRevert = false;
          var reverted = findRevertedCommit(commitsMap, commit);
          if (reverted) {
            commit.isRevert = true;
            this.reverted_map[reverted.hash] = commit;
          }

          commit.isReland = false;
          var relanded = findRelandedCommit(commitsMap, commit);
          if (relanded) {
            commit.isReland = true;
            this.relanded_map[relanded.hash] = commit;
          }
        }

        for (var i = 0; i < commits.length; i++) {
          var commit = commits[i];
          commit.ignoreFailure = commit.comments &&
                                 commit.comments.length > 0 &&
                                 commit.comments[commit.comments.length-1].ignoreFailure;
          if (this.reverted_map[commit.hash]) {
            commit.ignoreFailure = true;
          }

          commit.displayClass = {};
          if (!task_details[commit.hash]) {
            task_details[commit.hash] = {};
          }
          for (var taskSpec in task_details[commit.hash]) {
            var task = task_details[commit.hash][taskSpec];
            task.colorClass = getTaskColorClass(task);

            if (!tasks[taskSpec]) {
              // This is the first time we've seen this task spec.
              tasks[taskSpec] = {};
              var taskSpecDetails = {
                  "comments": data.taskSpecComments[taskSpec] || [],
                  "name": taskSpec,
                  // We're traveling backward in time, so the first task we
                  // find for a given task spec is its most recent.
                  "colorClass": task.colorClass,
                  "flaky": false,
                  "ignoreFailure": false,
              };
              var split = taskSpec.split("-");
              if (split.length >= 2 && VALID_TASK_SPEC_CATEGORIES.indexOf(split[0]) != -1) {
                  taskSpecDetails.category = split[0];
                  taskSpecDetails.subcategory = split[1];
              }
              if (taskSpecDetails.comments && taskSpecDetails.comments.length > 0) {
                taskSpecDetails.flaky = !!taskSpecDetails.comments[taskSpecDetails.comments.length-1].flaky;
                taskSpecDetails.ignoreFailure = !!taskSpecDetails.comments[taskSpecDetails.comments.length-1].ignoreFailure
              }
              task_specs[taskSpec] = taskSpecDetails;
            }
            tasks[taskSpec][task.id] = task;
            // Figure out the display class to use.
            var classes = [CLASS_TASK_SINGLE];
            if (i > 0) {
              // We are drawing from most recent on back in time.  prevCommit is really the "next"
              // commit in a temporal timeline.  But, it was the previously drawn commit, so the
              // name sticks.
              var prevCommit = commits[i-1];
              var prevDetails = task_details[prevCommit.hash] || {};
              if (prevCommit.parent.indexOf(commit.hash) === -1) {
                // We skipped one or more commits.  This is likely due to a branch.  We need to find the last drawn commit whose parent is this one.
                prevCommit = undefined;
                for (var j = i-1; j>= 0; j--) {
                  if (commits[j].parent.indexOf(commit.hash) !== -1) {
                    prevCommit = commits[j];
                    break;
                  }
                }
                if (prevCommit) {
                  // If the previously drawn commit does not exist, it basically means we are the
                  // head of the branch.  If it does exist, we change it to have a dashed bottom
                  // and for this commit to have a dashed top.
                  prevDetails = task_details[prevCommit.hash] || {};
                  var prevTask = prevDetails[taskSpec];
                  // Only continue drawing if it's actually the same task
                  if (prevTask && prevTask.id == task.id) {
                    classes = [CLASS_TASK_BOTTOM, CLASS_DASHED_TOP];

                    if (prevCommit.displayClass[taskSpec].indexOf(CLASS_TASK_SINGLE) >= 0) {
                      prevCommit.displayClass[taskSpec] = [CLASS_TASK_TOP, CLASS_DASHED_BOTTOM];
                    } else {
                      prevCommit.displayClass[taskSpec] = [CLASS_TASK_MIDDLE, CLASS_DASHED_BOTTOM];
                    }

                  }
                }
              } else if (prevDetails) {
                var prevTask = prevDetails[taskSpec];
                // Only continue drawing if it's actually the same task
                if (prevTask && prevTask.id == task.id) {
                  classes = [CLASS_TASK_BOTTOM];
                  var prevClasses = prevCommit.displayClass[taskSpec];
                  if (prevClasses.indexOf(CLASS_TASK_SINGLE) >= 0) {
                    prevCommit.displayClass[taskSpec] = [CLASS_TASK_TOP];
                  } else if (prevClasses.indexOf(CLASS_TASK_BOTTOM) >= 0) {
                    var j = prevClasses.indexOf(CLASS_TASK_BOTTOM);
                    prevClasses[j] = CLASS_TASK_MIDDLE;
                    prevCommit.displayClass[taskSpec] = prevClasses;
                  }
                }
              }
            }
            commit.displayClass[taskSpec] = classes;
          }
        }
        this._makeCommitsMap(commits);
        this.set("tasks", tasks);
        this.set("task_details", task_details);
        this.set("task_specs", task_specs);
        this._filterTaskSpecs();

        // Add autoroll tags as branch heads.
        var filteredBranchHeads = [];
        for (var i = 0; i < data.branch_heads.length; i++) {
          var b = data.branch_heads[i];
          filteredBranchHeads.push(b);
        }
        for (var i = 0; i < this.roll_statuses.length; i++) {
          var roll = this.roll_statuses[i];
          if (roll.lastRollRev) {
            filteredBranchHeads.push({
                name: roll.name + " rolled",
                head: roll.lastRollRev,
            });
          }
          if (roll.currentRollRev) {
            filteredBranchHeads.push({
              name: roll.name + " rolling",
              head: roll.currentRollRev,
            });
          }
        }

        this.set("branch_heads", filteredBranchHeads);

        var timeIdx = 0;
        var now = new Date();
        var time_points = {};

        // If the first commit happened after our first time point cutoff, we advance past it.
        while ((timeIdx < TIME_POINTS.length) && (now - TIME_POINTS[timeIdx].offset) > new Date(commits[0].timestamp)) {
          timeIdx++;
        }

        // Going backwards in time, we place a marker if the current commit happened before the time offset and the following commit happened after.  Once we find a cutoff, start looking for the next time point.
        var commitIdx = 0;
        while (commitIdx < (commits.length - 1) && timeIdx < TIME_POINTS.length) {
          var c = commits[commitIdx];
          var curr = new Date(c.timestamp);
          var next = new Date(commits[commitIdx+1].timestamp);

          if ((now - TIME_POINTS[timeIdx].offset) <= curr && (now - TIME_POINTS[timeIdx].offset) > next) {
            time_points[c.hash] = TIME_POINTS[timeIdx];
            timeIdx++;
            // We don't increment commitIdx because we want to double check the current cutoff.
            // Example: commit A happened 59 minutes ago and commit B happened 1.3 days ago.
            // The time point between them should be the -1d one, not the -1h one. Since time_points
            // is based off of commit, we can recheck and replace the shorter cutoffs if necessary.
          } else {
            commitIdx++;
          }
        }

        // Check for the last commit as well, except we don't compare it to the following commit.
        var last = commits[commits.length - 1];
        if ((timeIdx < TIME_POINTS.length) && (now - TIME_POINTS[timeIdx].offset) <= last.timestamp) {
          time_points[last.hash] = TIME_POINTS[timeIdx];
        }

        console.timeEnd("_processData");
        this.set("_filtering", false);

        // Actually draw the commits.
        this.set("commits", commits);
        this.set("time_points", time_points);
      },

      // Apply the desired filter to the tasks.
      _filterTaskSpecs: function() {
        console.time("filterTaskSpecs");
        var filteredTaskSpecs = [];
        var selected = this.filter || FILTER_DEFAULT;
        if (selected === FILTER_DEFAULT) {
          if (this.is_sheriff || this.is_trooper) {
            selected = FILTER_FAILURES;
          } else {
            selected = FILTER_INTERESTING;
          }
        }
        if (selected == FILTER_ALL) {
          for (var taskSpec in this.task_specs) {
            filteredTaskSpecs.push(taskSpec);
          }
        } else if (selected == FILTER_INTERESTING || selected == FILTER_FAILURES || selected == FILTER_FAIL_NO_COMMENT) {
          for (var taskSpec in this.task_specs) {
            var failed = false;
            var succeeded = false;
            for (var taskId in this.tasks[taskSpec]) {
              var task = this.tasks[taskSpec][taskId];
              if (task.status == TASK_STATUS_PENDING || task.status == TASK_STATUS_RUNNING) {
                continue;
              }
              // If interesting or "failing w/o comment" is selected, compute ignoreFailure
              // and skip this task if it belongs entirely to commits that have been ignored.
              if (selected === FILTER_INTERESTING || selected === FILTER_FAIL_NO_COMMENT) {
                var commits = task.commits || [];
                var isIgnored = commits.length > 0;
                commits.forEach(function(c){
                  var o = this.commits_map[c];
                  isIgnored = isIgnored && o && o.ignoreFailure;
                }.bind(this));
                if (isIgnored) {
                  continue;
                }
              }

              if (task.status == TASK_STATUS_SUCCESS) {
                succeeded = true;
              } else {
                failed = true;
              }
              if (selected == FILTER_INTERESTING) {
                if (succeeded && failed && !this.task_specs[taskSpec].ignoreFailure) {
                  filteredTaskSpecs.push(taskSpec);
                  break;
                }
              } else if (selected == FILTER_FAILURES) {
                if (failed) {
                  filteredTaskSpecs.push(taskSpec);
                  break;
                }
              } else if (selected == FILTER_FAIL_NO_COMMENT) {
                if (task.status != TASK_STATUS_SUCCESS && (!this.task_specs[taskSpec].comments || this.task_specs[taskSpec].comments.length == 0)) {
                  if (!task.comments || task.comments.length == 0) {
                    filteredTaskSpecs.push(taskSpec);
                    break;
                  }
                }
              }
            }
          }
        } else if (selected == FILTER_COMMENTS) {
          for (var taskSpec in this.task_specs) {
            if (this.task_specs[taskSpec].comments && this.task_specs[taskSpec].comments.length > 0) {
              filteredTaskSpecs.push(taskSpec);
              continue;
            }
            for (var taskId in this.tasks[taskSpec]) {
              var task = this.tasks[taskSpec][taskId];
              if (task.status == TASK_STATUS_PENDING || task.status == TASK_STATUS_RUNNING) {
                continue;
              }
              if (task.comments && task.comments.length > 0) {
                filteredTaskSpecs.push(taskSpec);
                break;
              }
            }
          }
        } else if (selected == FILTER_SEARCH) {
          var matchText = this.search;
          for (var taskSpec in this.task_specs) {
            if (taskSpec.toLowerCase().match(matchText.toLowerCase())) {
              filteredTaskSpecs.push(taskSpec);
            }
          }
        } else {
          console.error("Invalid task spec filter selection: " + selected);
        }
        sk.sortStrings(filteredTaskSpecs);

        var categories = {};
        var categoryList = [];
        var purpleTasks = [];
        for (var i = 0; i < filteredTaskSpecs.length; i++) {
          var taskSpecName = filteredTaskSpecs[i];
          var category = this.task_specs[taskSpecName].category;
          if (!category) {
            category = "Other";
          }
          if (!categories[category]) {
            categories[category] = {
              colspan: 0,
              subcategoryList: [],
              subcategories: {},
            };
            categoryList.push(category);
          }
          var subcategory = this.task_specs[taskSpecName].subcategory;
          if (!subcategory) {
            subcategory = "Other";
          }
          if (!categories[category].subcategories[subcategory]) {
            categories[category].subcategories[subcategory] = {
              task_specs: [],
            };
            categories[category].subcategoryList.push(subcategory);
          }
          categories[category].subcategories[subcategory].task_specs.push(taskSpecName);
          categories[category].colspan++;

          // Find any purple tasks for this task spec.

          // Exclude the Google3-Autoroller since it is not a real bot and
          // therefore cannot be retried.
          if (taskSpecName != "Google3-Autoroller") {
            for (var taskId in this.tasks[taskSpecName]) {
              var task = this.tasks[taskSpecName][taskId];
              if (task.status == TASK_STATUS_MISHAP) {
                // TODO(borenet): This is a bit of a hack.
                // Jobs are named after task, test, or perf tasks, but not
                // uploads. If this is an upload, trim the prefix.
                var jobName = taskSpecName;
                if (jobName.startsWith("Upload-")) {
                  jobName = jobName.substring("Upload-".length);
                }
                purpleTasks.push({"name": jobName, "commit": task.revision});
              }
            }
          }
        }
        this.set("categories", categories);
        this.set("category_list", categoryList);
        this.set("purple_tasks", purpleTasks);
        console.timeEnd("filterTaskSpecs");
      },

      _searchChanged: function() {
        // This callback fires every time the user presses a key inside the
        // input box. Updating the display can be really slow when there are
        // a lot of task specs, so we should wait until the user is done typing
        // before re-filtering.
        if (this.taskSpecSearchChangedTimeout) {
          window.clearTimeout(this.taskSpecSearchChangedTimeout);
        }
        this.taskSpecSearchChangedTimeout = window.setTimeout(function() {
          this.taskSpecSearchChangedTimeout = null;

          // If "search" is already selected, filter the task specs.
          if (this.filter == "search") {
            this._filterTaskSpecs();
          }
        }.bind(this), 400);
      },

      forceUpdate: function() {
        this._startUpdate(false);
      },

      forceReProcess: function() {
        this._processData(this._data, this.roller_statuses);
      },
    });
    })();
  </script>
</dom-module
