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

  An element to display information on one or more commits.

  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.

  Methods:
    setCommitInfo - Sets the commit info, an array of *types.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 []*types.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
        }
      },

      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) {
        this._commitinfo = commitinfo;
        this._processCommitInfo();
      },

      selectHash: function(hash) {
        $$('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) {
          var lastHash = this._commitinfo[0].hash;
          this._firstHash = this._commitinfo[this._commitinfo.length - 1].hash;
          if (!this._commitinfo[0].message) {
            var url = this.repo + '/+log/' + this._firstHash + '~' + 1 + '..' + lastHash + '?format=json';
            // The git hashes are in time order, but not contiguous, so request
            // the log range and them populate messages by matching git hashes.
            sk.get(url).then(this._removeSecurityHeader).then(JSON.parse).then(function (json) {
              var len = this._commitinfo.length;
              for (var i = 0; i < json.log.length; i++) {
                var commit = json.log[i].commit;
                // The git hash of this log meesage.
                for (var j = 0; j < len; j++) {
                  if (this._commitinfo[j].hash == commit) {
                    this.set('_commitinfo.'+j+'.message', json.log[i].message.slice(0, 60));
                    break;
                  }
                }
              }
              // This can go away once we start filling in the message on the server side.
              $$('commit-sk', this).forEach(function(ele) {
                ele.refresh();
              });
              this.fire('commits-loaded', {});
            }.bind(this)).catch(sk.errorMessage);
          }
          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) {
        return s.slice(4, s.length);
      },

      _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>
