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

  Shows the results of a search request.
  It sends the query string as a JSON request to the
  search entpoint ('/json/search') and renders the result.

  It assumes to the be part of a client site routed system
  of views and therefore offers the 'pageSelected' and 'pageUnselected'
  functions. These need to be called whenever the page goes
  in and out of view.

  Attributes:
    None

  Methods:
    pageSelected(ctx) - Called by the router when the view becomes visible.
          ctx is the context provided in the route dispatch of page.js.

    pageDeselected - Called by the router when the view is no longer visible.

  Events:
    None

  Mailboxes:
    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/iron-icons/iron-icons.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="bower_components/paper-toggle-button/paper-toggle-button.html">

<link rel="import" href="activity-sk.html">
<link rel=import href="detail-list-sk.html">
<link rel=import href="digest-details-sk.html">
<link rel=import href="search-controls-sk.html">
<link rel=import href="trybot-controls-sk.html">
<link rel="import" href="../common/imp/triage-sk.html">

<dom-module id="search-page-sk">
  <template>
    <style include="iron-flex iron-flex-alignment"></style>
    <style include="shared-styles">
      digest-details-sk {
        display: block;
        box-shadow: 3px 3px 6px 1px rgba(133,133,133,1);
        margin-top: 1em;
        margin-bottom: 1em;
        margin-left: 0;
        margin-right: 0;
        padding-left: 1em;
        padding-top: 1em;
        padding-bottom: 1em;
        padding-right: 0;
      }

      digest-details-sk[data-focus] {
        box-shadow: 3px 3px 6px 5px #FF7F00;
      }

      #missing {
        padding-top: 2em;
      }

      .searchPageWrapper {
        padding-left: 1em;
        padding-top: 1em;
        margin-left:1em;
        margin-right: 3em;
      }

      #triggerSearchButton {
        font-size: 18px;
      }

      .helpIconContainer {
        padding-left: 3em;
      }

      paper-button {
        min-width: 2em;
        margin: 5px;
        background: #eee;
      }

      .actionMenu {
        max-width: 10em;
        margin-left: 10em;
      }

      .actionButton {
        color: green;
      };

      #closestButton[raised] > iron-icon {
        color: #bbb;
      }

      #closestButton[raised] {
        background: #fff;
      }

      #closestButton:hover,
      #closestButton[raised]:hover {
        background: #ddd;
      }

      .searchResponse {
        padding: 1em 1em  0 1em;
        margin: 1em 1em 1em 0;
        border: 1px solid #555555;
      }

      .searchStats {
        padding-bottom: 1em;
      }
    </style>

    <div class="searchPageWrapper layout vertical">
      <activity-sk id="activityBar" busy="{{_hideAll}}"></activity-sk>
      <div class="layout horizontal">
          <search-controls-sk id="searchControls" beta></search-controls-sk>
          <div>
            <paper-button id="triggerSearchButton" raised disabled="[[_hideAll]]">Search</paper-button>
          </div>

          <paper-menu-button close-on-activate no-animations class="actionMenu">
            <paper-button class="dropdown-trigger actionButton" raised>Actions</paper-button>
            <paper-menu class="dropdown-content">
              <paper-item id="actionTestView">Switch To Test View</paper-item>
              <paper-item id="actionBulkTriage">Bulk Triage</paper-item>
              <paper-item id="actionExport">Export</paper-item>
              <paper-item id="actionLegacySearch">Legacy Search</paper-item>
              <paper-item id="actionHelpDialog">Help</paper-item>
            </paper-menu>
          </paper-menu-button>
      </div>

      <div class="searchResponse" hidden$="[[_noResult(_allData)]]">
        <div class="searchStats">
          Displaying: [[_allData.size]] of [[_allData.digests.length]] images starting at [[_allData.offset]]<br>
          UniqueTests Visible: [[_uniqueTests.length]] <br>
          UniqueTests Total: [[_uniqueTestsAll.length]]<br>
        </div>
        <trybot-controls-sk id="trybotControls"></trybot-controls-sk>
      </div>
      <div hidden$="[[_hideAll]]">
        <div id="missing" hidden$="[[_nonEmptyResult(data)]]">
          No digests match your query.
        </div>
        <div hidden$="[[_emptyResult(data)]]">
          <detail-list-sk id="detailList">
            <template is="dom-repeat" items="[[data.digests]]">
              <digest-details-sk
                      id$="[[_entryId(item)]]"
                      mode="list"
                      triage
                      details="[[item]]"
                      commits="[[data.commits]]"
                      metric="[[_state.metric]]"
                      issue="[[data.issue.id]]">
              </digest-details-sk>
            </template>
          </detail-list-sk>
        </div>
      </div>
    </div>
    <paper-dialog id="bulkDialog" with-backdrop>
      <h2>Bulk Triage</h2>
      <p>Assign the status to all images on this page at once.</p>
      <div class="layout horizontal">
        <triage-sk value="{{_bulkStatus}}" id="triageControls"></triage-sk>
        <paper-button id="closestButton" on-tap="_handleClosestButton" title="Assign status of closest image">
          <iron-icon icon="icons:view-agenda"></iron-icon>
        </paper-button>
      </div>
      <div hidden$="[[_noMore(_allData)]]">
        <paper-toggle-button checked="{{_triageAll}}">Triage all [[_getBulkTriageCount(_allData.digests, _bulkStatus)]].</paper-toggle-button>
      </div>
      <div class="buttons">
        <paper-button raise dialog-dismiss>Cancel</paper-button>
        <paper-button raise dialog-dismiss on-tap="_doBulkTriage" disabled="[[!_bulkStatus]]">Triage</paper-button>
      </div>
    </paper-dialog>

  </template>
  <script>
    Polymer({
      is: "search-page-sk",

      behaviors: [gold.PageStateBehavior],

      properties: {
        data: {
          type: Object,
          value: function() { return {}; }
        },
        _bulkStatus: {
          type: String,
          value: "",
          observer: "_handleBulkStatusChanged"
        },
        _triageAll: {
          type: Boolean,
          value: false
        }
      },

      ready: function() {
        this.listen(this.$.searchControls, 'state-change', '_handleStateChange');
        this.listen(this.$.trybotControls, 'state-change', '_handleStateChange');
        this.listen(this.$.trybotControls, 'state-update', '_handleStateUpdate');
        this.listen(this.$.triggerSearchButton, 'tap', '_handleSearchButton');
        this.listen(this.$.actionTestView, 'tap', '_handleSwitchToByTest');
        this.listen(this.$.actionBulkTriage, 'tap', '_handleBulkButton');
        this.listen(this.$.actionExport, 'tap', '_handleExport');
        this.listen(this.$.actionLegacySearch, 'tap', '_handleLegacySearchButton');
        this.listen(this.$.actionHelpDialog, 'tap', '_openHelpDialog');
        this._setDefaultState(gold.defaultSearchState, false);
      },

      pageSelected: function(ctx) {
        this.set('data', {});
        this.set('_allData', {});
        this.$.detailList.startUse();

        // Initialize the state and set values of the controls.
        this._initState(ctx, this._getDefaultStateWithCorpus());
        this.$.searchControls.setState(this._state);
        this.$.trybotControls.setState(this._state);

        // load the commits, parameters and data.
        this._loadCommits();
        this._loadParamset();
        this._load();
      },

      pageDeselected: function() {
        this.$.detailList.endUse();
      },

      _handleSearchButton: function(ev) {
        // Reload the page with the current state of the controls.
        this._redirectToState(this.$.searchControls.state);
      },

      _handleStateChange: function(ev) {
        // Reload the page with the new  state in the query parameters.
        this._redirectToState(ev.detail);
      },

      _handleStateUpdate: function(ev) {
        // Update the state and the URL and then distribute the new state to
        // the control elements.
        this._replaceState(ev.detail);
        this.$.searchControls.setState(this._state);
        this.$.trybotControls.setState(this._state);
      },

      _handleSwitchToByTest: function() {
        this._redirectToState({}, "/list");
      },

      _openHelpDialog: function(ev) {
        this.$.detailList.openHelpDialog();
      },

      _handleBulkButton: function(ev) {
        this.set("_bulkStatus", "");
        this.set("_triageAll", false);
        this.$.bulkDialog.open();
      },

      _handleExport: function(ev) {
        var url = this._getRedirectURL({}, "/json/export");
        window.open(url, "_blank");
      },

      _handleLegacySearchButton: function(ev) {
        this._redirectToState({}, "/legacysearch");
      },

      _handleClosestButton: function(ev) {
        this.set("_bulkStatus", '=');
      },

      _handleBulkStatusChanged: function(newVal) {
        if (newVal === '=') {
          Polymer.dom(this.$.closestButton).removeAttribute('raised');
        } else {
          Polymer.dom(this.$.closestButton).setAttribute('raised', '');
        }
      },

      // _statusClosest returns label based on whether the digest is closest to
      // a positive or negative image.
      _statusClosest:function(digest) {
         if (digest.closestRef === gold.REF_NEG) {
           return gold.NEGATIVE;
        }
        return gold.POSITIVE;
      },

      // _getBulkTriageCount returns the number of digests that will be triaged
      // in a bulk triage operation.
      _getBulkTriageCount: function(digests, bulkStatus) {
        if (bulkStatus !== '=') {
          return digests.length;
        }

        // If we compare to the closest we only show the number of digests
        // that actually have a reference image.
        var count = 0;
        for(var i=0; i < digests.length; i++) {
          if (digests[i].closestRef !== '') {
            count++;
          }
        }
        return count;
      },

      _doBulkTriage: function(ev) {
        var targetStatus = this.$.triageControls.value;
        var digests = (this._triageAll) ? this._allData.digests : this.data.digests;
        var triageList = [];
        if (targetStatus === '=') {
          for(var i=0; i < digests.length; i++) {
            if (digests[i].closestRef !== '') {
              var status = this._statusClosest(digests[i]);
              triageList.push([digests[i].test, digests[i].digest, status]);
            }
          }
        } else {
          for(var i=0; i < digests.length; i++) {
            triageList.push([digests[i].test, digests[i].digest, targetStatus]);
          }
        }
        var query = new gold.TriageQuery(triageList);
        query.setIssue(sk.robust_get(this._issue, ["id"]));
        this.$.activityBar.startSpinner("Triaging ...");
        sk.post('/json/triage', JSON.stringify(query)).then(function() {
          this.$.activityBar.stopSpinner();
        }.bind(this)).catch(function(e) {
          this.$.activityBar.stopSpinner();
          sk.errorMessage(e);
        }.bind(this));
      },

      _load: function() {
        this.$.activityBar.startSpinner("Loading ...");

        var q = window.location.search;
        sk.get("/json/search" + q).then(JSON.parse).then(function (json) {
          // Split out the digests that are being displayed and keep a copy
          // of all digests that matched the query.
          var displayData = sk.object.shallowCopy(json);
          displayData.digests = displayData.digests.slice(json.offset, json.offset+json.size);
          this.set('_allData', json);

          this.set('_uniqueTestsAll', this._getUniqueTests(json.digests));
          this.set('_uniqueTests', this._getUniqueTests(displayData.digests));

          this.set('data', displayData);
          this.set('_issue', json.issue);
          this.$.trybotControls.setIssue(json.issue);
          this.$.activityBar.stopSpinner();
        }.bind(this)).catch(function(e) {
          this.$.activityBar.stopSpinner();
          sk.errorMessage(e);
        }.bind(this));
      },

      _getUniqueTests: function(digests) {
        var unique = {};
        for(var i=0; i < digests.length; i++) {
          unique[digests[i].test] = true;
        }
        return Object.keys(unique);
      },

      _loadCommits: function() {
        sk.get("/json/commits").then(JSON.parse).then(function (json) {
          this.$.searchControls.setCommitInfo(json);
          this._commits = json;
        }.bind(this)).catch(sk.errorMessage);
      },

      _loadParamset: function() {
        sk.get("/json/paramset").then(JSON.parse).then(function (json) {
          this.$.searchControls.setParamSet(json);
          this._paramSet = json;
        }.bind(this)).catch(sk.errorMessage);
      },

      _entryId: function(item) {
        // Make sure it's a valid selector.
        return (item.test + '_' + item.digest).replace(/[^_A-Za-z0-9]/g, '_');
      },

      // Returns true if there was a query and result is not empty.
      _nonEmptyResult: function(data) {
        return !data.digests || data.digests.length > 0;
      },

      // Returns true if there was a query and the result is empty.
      _emptyResult: function(data) {
        return !data.digests || data.digests.length === 0;
      },

      _noResult: function(data) {
        return !data.digests;
      },

      _noMore: function(allData) {
        return (allData.digests && allData.digests.length <= allData.size);
      }
    });
  </script>
</dom-module>
