<!-- The <failures-page-sk> custom element declaration.

  The failures-page-sk custom element renders the list of digests that could
  not be downloaded or decoded.

  Attributes: None

  Events: None

  Methods: None

-->
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">

<link rel="import" href="activity-sk.html">
<link rel="import" href="shared-styles.html">

<dom-module id="failures-page-sk">
  <template>
    <style include="shared-styles"></style>
    <style include="iron-flex iron-flex-alignment">
      .digestHeader,
      .dateTimeHeader,
      .reasonHeader {
        font-weight: bold;
      }

      .digestHeader,
      .digestValue {
        width: 20em;
      }

      .dateTimeHeader,
      .dateTimeValue {
        width: 15em;
      }

      .reasonHeader,
      .reasonValue {
        width: 12em;
      }

      .headerContainer {
        padding-top: 2em;
      }

      .bulkButtons {
        padding: 1em 0 1em 0;
      }
    </style>
    <h2>Digest Failures</h2>
    <activity-sk id="activityFailures"></activity-sk>
    <template is="dom-if" if="[[_emptyResponse(_failureSummary)]]">
      <div class="emptyResponse">No failure records found.</div>
    </template>
    <template is="dom-if" if="[[_nonEmptyResponse(_failureSummary)]]">
      <div>Showing the most recent [[_failureSummary.failures.length]] of [[_failureSummary.count]] failures.</div>
      <div class="bulkButtons">
        <paper-button raised on-tap="_handleClearAll" title="Remove from server cache">Clear All</paper-button>
        <paper-button raised on-tap="_handlePurgeAll" title="Remove from cache and Google storage">Purge All</paper-button>
      </div>
      <table class="headerContainer">
        <thead>
          <tr>
            <td class="dateTimeHeader">Date/Time</td>
            <td class="digestHeader">Digest</td>
            <td class="reasonHeader">Reason</td>
            <td>&nbsp;</td>
            <td>&nbsp;</td>
          </tr>

          <template is="dom-repeat" items="[[_failureSummary.failures]]" as="entry">
            <tr>
              <td class="dateTimeValue">[[_toLocalDate(entry.ts)]]</td>
              <td class="digestValue"><a href$="[[_imgHref(entry)]]" target="_blank" rel="noopener">[[entry.digest]]</a></td>
              <td class="reasonValue">[[entry.reason]]</td>
              <td><paper-button on-tap="_handleClear" title="Remove from server cache" data-digestid$="[[entry.digest]]">Clear</paper-button></td>
              <td><paper-button on-tap="_handlePurge" title="Remove from cache and Google storage" data-digestid$="[[entry.digest]]">Purge</paper-button></td>
            </tr>
          </template>
        </thead>
      </table>
    </template>
  </template>
  <script>
    Polymer({
      is: 'failures-page-sk',

      properties: {
        _failureSummary: {
          type: Object,
          value: null
        }
      },

      pageSelected: function() {
        // Fetch the list of failures from the backend.
        var url = '/json/failure';
        gold.loadWithActivity(this, url, this.$.activityFailures, '_failureSummary');
      },

      pageDeselected: function() {},

      // _clear removes a failure entry from the backend. If gsPurge is true it will
      // cause the backend to also remove the digest from Google Storage.
      _clear: function (digests, gsPurge) {
        var url = '/json/failure/clear' + ((gsPurge) ? '?purge=true':'');
        this.$.activityFailures.startSpinner("Loading...");
        sk.post(url, JSON.stringify(digests)).then(JSON.parse).then(function(json){
          this.set('_failureSummary', json);
          this.$.activityFailures.stopSpinner();
        }.bind(this)).catch(function(err) {
          this.$.activityFailures.stopSpinner();
          sk.errorMessage(err);
        }.bind(this));
      },

      _clearAll: function(gsPurge) {
        var digests = [];
        for(var i=0; i < this._failureSummary.failures.length; i++) {
          digests.push(this._failureSummary.failures[i].digest);
        }
        this._clear(digests, gsPurge);
      },

      _handleClear: function (event) {
        this._clear([event.target.dataset.digestid], false);
      },

      _handlePurge: function (event) {
        this._clear([event.target.dataset.digestid], true);
      },

      _handleClearAll: function(event) {
        this._clearAll(false);
      },

      _handlePurgeAll: function() {
        this._clearAll(true);
      },

      _toLocalDate: function (timeStampMs) {
        return new Date(timeStampMs).toLocaleString();
      },

      _imgHref: function (entry) {
        return gold.imgHref(entry.digest);
      },

      _emptyResponse: function(failureSummary) {
        return failureSummary && failureSummary.count === 0;
      },

      _nonEmptyResponse: function(failureSummary) {
        return failureSummary && !this._emptyResponse(failureSummary);
      }
    });
  </script>
</dom-module>
