<!--
  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 an issue number that was relanded to the commit that relands it
    reverted_map: Object, a map of an issue number that was reverted to the commit 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_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: https:\/\/skia-review.googlesource.com\/(c\/)?([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",
        },
        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,
        },
        _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;
        }
        sk.get(url).then(JSON.parse).then(function(json) {
          // Clear out the existing data if necessary.
          if (json.start_over || fromScratch) {
            this._clearData();
          }

          // 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.issue] = commit;
          }

          commit.isReland = false;
          var relanded = findRelandedCommit(commitsMap, commit);
          if (relanded) {
            commit.isReland = true;
            this.relanded_map[relanded.issue] = 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.issue]) {
            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_ALL;
        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
