<!-- The <commits-panel-sk> custom element declaration.

  An element to display information on one or more commits. There is some added complexity
  because the tiles storing commits do not keep track of the commit message. Thus,
  this element will make an XHR to the repo (or the server, see origin) for the
  commit message of a given commit.

  Attributes:
    progress - Boolean, if true then display the percent complete
      for the first hash.

    selection - Boolean, if true then selections are displayed, i.e. the user
      click on a commit and select it.

    selector - The iron-selector element that wraps the commits.

    mailbox - The sk.Mailbox name to listen for the data to populate
      the element. This is in addition to the 'commits' mailbox
      described below.

    repo - The URL of the underlying git repo. This assumes a
           googlesource repo when deriving URLs from this value.

    commitinfo - A list of commits that are passed to setCommitInfo (see below).
           This is the direct way to set commits.

    origin - a Boolean, if true, indicates the base server should be queried for the commit
             messages instead of the repo. This can help prevent CORS errors.

  Methods:
    setCommitInfo - Sets the commit info, an array of *tiling.Commit. See the
      description for the commits Mailbox for more details.

    selectHash - Forces the selection of the given hash.

  Events:
    commit-selected - Event produced when a commit is selected. The event
      detail contains:

      {
        description: "fixed lengh string descripting the commit",
        hash: "1213982193 (the commit hash)",
      }

  Mailboxes:
    commits - The sk.Mailbox name to listen for the data to populate
      the element. The mailbox data needs to be a serialized slice
      of []*tiling.Commit. If not set then the data must be supplied
      by the setCommitInfo method.

        [
          {
            commit_time: 1439649751,
            author: "reed (reed@chromium.org)",
            hash: "bb886749feb444edfd8fbf053a9ea815e3605f8a",
          },
          {
            author: "reed (reed@chromium.org)",
            commit_time: 1439648914,
            hash: "e02716908fe82c7c4ae9b415793277620a22bcd6",
          },
        ]

      Note that the hashes need to be in order, but not necessarily
      contiguous. Note that they also need to be supplied in time ascending
      order, that is, the commit at index 0 needs to be the oldest commit, and
      the last commit in the array needs to be the newest commit.

-->
<link rel="stylesheet" href="/res/common/css/md.css">
<link rel="import" href="/res/imp/bower_components/iron-selector/iron-selector.html">
<link rel="import" href="commit.html">

<dom-module id="commits-panel-sk">
  <template>
    <style type="text/css" media="screen">
      div {
        margin-bottom: 0.5em;
      }

      commit-sk {
        display: block;
        padding-right: 2em;
      }

      pre {
        font-size: 14px;
        margin: 0.2em 0;
        padding: 0.3em;
      }

      .iron-selected {
        background: #eee;
      }

      :host {
        display: block;
      }
    </style>
    <template is="dom-if" if="{{progress}}">
      <div>
        <a target="_blank" href$="{{_statusHref(_firstHash)}}">Buildbot Percent Complete: <span>{{_commitPercent(_percent)}}</span>%</a>
      </div>
    </template>
    <iron-selector id=selector>
      <template is="dom-repeat" items="{{_commitinfo}}" as="c">
        <commit-sk data-hash$="{{c.hash}}" hash="{{c.hash}}" commit="{{c}}" repo="{{repo}}"></commit-sk>
      </template>
    </iron-selector>
  </template>
  <script>
    Polymer({
      is: 'commits-panel-sk',

      properties: {
        progress: {
          type: Boolean,
          value: false,
          reflectToAttribute: true,
        },
        selection: {
          type: Boolean,
          value: false,
          reflectToAttribute: true,
          observer: "_selectionChanged",
        },
        mailbox: {
          value: "",
          reflectToAttribute: true
        },
        repo: {
          type: String,
          value: "https://skia.googlesource.com/skia",
          notify: true
        },

        origin: {
          type: Boolean,
          value: false
        },

        commitinfo: {
          type: Array,
          value: null,
          observer: "setCommitInfo"
        }
      },

      listeners: {
        "selector.iron-select": "_selectorTap",
      },

      ready: function () {
        this._percent = -1.0;
        this._firstHash = '';
        this.selector = this.$.selector;
        sk.Mailbox.subscribe('commits', this.setCommitInfo.bind(this));

        if (this.mailbox != "") {
           sk.Mailbox.subscribe(this.mailbox, this.setCommitInfo.bind(this));
        }
      },

      setCommitInfo: function(commitinfo) {
        if (commitinfo) {
          this._commitinfo = commitinfo;
          this._processCommitInfo();
        }
      },

      selectHash: function(hash) {
        // Clear the selection.
        this.selector.selected = null;

        // If the commits have been set then use them to find the hash. This
        // avoids timing issues if the commit-sk elements haven't rendered yet.
        if (this._commitinfo && (this._commitinfo.length > 0)) {
          var idx = this._commitinfo.findIndex(function(c) { return c.hash === hash; });
          if (idx >= 0) {
            this.selector.select(idx);
          }
          return;
        }

        $$('commit-sk', this).forEach(function(ele) {
          if (ele.dataset.hash === hash) {
            this.selector.select(this.selector.indexOf(ele));
          }
        }.bind(this));
      },

      _selectorTap: function(e) {
        var detail = {
          description: e.detail.item.asString(),
          commit: e.detail.item.commit,
        };
        this.dispatchEvent(new CustomEvent('commit-selected', { detail: detail, bubbles: true }));
      },

      _selectionChanged: function() {
        this.$.selector.selectedClass = this.selection ? "iron-selected" : "no-matching-class";
      },

      _processCommitInfo: function () {
        if (this._commitinfo && this._commitinfo.length) {
          this._firstHash = this._commitinfo[this._commitinfo.length - 1].hash;
          if (this._commitinfo[0].message) {
            // Fire the message even when the commit messages were cached.
            this.fire('commits-loaded', {});
          } else {
            // This should not happen anymore, because commits sent to the frontend include the
            // message by default.
            console.error('no messages?');
          }
          if (this.progress) {
            var url = 'https://status.skia.org/json/skia/buildProgress?commit=' + this._firstHash;
            // The status server returns JSON of the form:
            //
            // {
            //   "commit": "e9e3ee33f30c14c31afd5fc3fe4dda7f15783c75",
            //   "finishedTasks": 111,
            //   "finishedProportion": 0.7762237762237763,
            //   "totalTasks": 143
            // }
            sk.get(url).then(JSON.parse).then(function (json) {
              this._percent = json.finishedProportion;
            }.bind(this)).catch(sk.errorMessage);
          }
        }
      },

      // _removeSecurityHeader strips the first 4 chars from the input. Needed
      // since googlesource.com prefixes all JSON responses with )]}' as an
      // XSS defense.
      _removeSecurityHeader: function (s) {
        if (s.startsWith(")]}'")) {
          return s.slice(4, s.length);
        }
        return s;
      },

      _commitPercent: function (p) {
        if (p == -1.0) {
          return "[calculating]";
        }
        return Math.round(p * 100);
      },

      _statusHref: function (hash) {
        return 'https://status.skia.org/?commit=' + hash + '&commitLabel=author&filter=all';
      },
    });
  </script>
</dom-module>
