<!--
  The common.js file must be included before this file.

  This in an HTML Import-able file that contains the definition
  of the following elements:

    <alert-controls-sk>

  To use this file import it:

    <link href="/res/imp/alert-controls-sk.html" rel="import" />

  Usage:

    <alert-controls-sk></alert-controls-sk>

  Properties:
    alert_name: String, The alert "name" or title. Used to make a "file bug" link.

    alert_url: String, URL associated with this alert.

    extra_params: Object, Any extra parameters to submit with POST requests.

    show_snooze: Boolean, Whether or not to show the "snooze" button.

    show_unsnooze: Boolean, Whether or not to show the "unsnooze" button.

  Methods:
    None

  Events:
    submit - Fired when a POST request which modifies an alert completes.
-->
<link rel="stylesheet" href="/res/common/css/md.css">
<link rel="import" href="/res/imp/bower_components/polymer/polymer.html">
<link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="/res/imp/bower_components/iron-icon/iron-icon.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/communication-icons.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="/res/imp/bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html">

<dom-module id="alert-controls-sk">
  <style include="iron-flex iron-flex-alignment iron-positioning">
  .bug-icon {
    fill: black;
    padding:7px;
    cursor: pointer;
  }
  </style>
  <template>
    <div class="flex horizontal layout">
      <paper-input value="{{_commentText}}" label="Comment" class="flex" on-change="_preventBubble"></paper-input>
      <template is="dom-if" if="[[show_snooze]]">
        <paper-icon-button icon="icons:alarm" on-click="_snoozeDialog" title="Snooze and add comment"></paper-icon-button>
      </template>
      <template is="dom-if" if="[[show_unsnooze]]">
        <paper-icon-button icon="icons:alarm-off" on-click="_unsnoozeAlert" title="Unsnooze and add comment"></paper-icon-button>
      </template>
      <paper-icon-button icon="icons:highlight-off" on-click="_dismissAlert" title="Dismiss and add comment"></paper-icon-button>
      <paper-icon-button icon="communication:comment" on-click="_addComment" title="Add comment"></paper-icon-button>
      <template is="dom-if" if="[[_getGoloLink(alert_name)]]">
        <a href$="[[_getGoloLink(alert_name)]]"
           title="File Chrome Infra Bug"
           target="_blank" rel="noopener">
          <iron-icon class="bug-icon" icon="icons:bug-report" ></iron-icon>
        </a>
      </template>
    </div>
    <paper-dialog id="snoozeDialog" heading="How long?" transition="paper-dialog-transition-center">
      <div>
        <paper-input type="number" label="Days" value="{{_snoozeDays}}" on-change="_preventBubble" always-float-label></paper-input>
        <paper-input type="number" label="Hours" value="{{_snoozeHours}}" on-change="_preventBubble" always-float-label></paper-input>
        <paper-input type="number" label="Minutes" value="{{_snoozeMins}}" on-change="_preventBubble" always-float-label></paper-input>
        <button on-click="_snoozeAlert" affirmative>Ok</button>
      </div>
    </paper-dialog>
  </template>
  <script>
  (function(){

    var bugRegex = new RegExp(".*Swarming bot (.*) is (quarantined|missing).*");

    var goloRegex = new RegExp(".*(a3|a4|m3|m5)");

    function getFileBugSVG(id) {
      return `https://bugs.chromium.org/p/chromium/issues/entry?summary=[Device%20Restart]%20for%20${id}&description=Please%20Reboot%20${id}&cc=rmistry@google.com&components=Infra%3ELabs&labels=Pri-2,Infra-Troopers,Restrict-View-Google`;
    }

    Polymer({
      is: "alert-controls-sk",

      properties: {

        alert_name: {
          type: String,
        },

        /**
         * URL associated with this alert.
         */
        alert_url: {
          type: String,
          value: "",
        },

        /**
         * Any extra parameters to submit with POST requests.
         */
        extra_params: {
          type: Array,
          value: function() { return []; },
        },

        /**
         * Whether or not to show the "snooze" button.
         */
        show_snooze: {
          type: Boolean,
          value: false,
        },

        /**
         * Whether or not to show the "unsnooze" button.
         */
        show_unsnooze: {
          type: Boolean,
          value: false,
        },

        _commentText: {
          type: String,
          value: "",
        },

        _snoozeDays: {
          type: Number,
          value: 0,
        },

        _snoozeHours: {
          type: Number,
          value: 0,
        },

        _snoozeMins: {
          type: Number,
          value: 0,
        },

      },

      _resetInputs: function() {
        this._commentText = "";
        this._snoozeDays = 0;
        this._snoozeHours = 0;
        this._snoozeMins = 0;
        this.$.snoozeDialog.close();
      },

      _post: function(action, params) {
        var postParams = {};
        for (var p in params) {
          postParams[p] = params[p];
        }
        for (var p in this.extra_params) {
          postParams[p] = this.extra_params[p];
        }
        sk.post(this.alert_url + "/" + action, JSON.stringify(postParams)).then(function (resp) {
          this._resetInputs();
          this.dispatchEvent(new CustomEvent("submit", {"alertUrl": this.alert_url, "action": action}));
        }.bind(this), function (err) {
          sk.errorMessage("Action failed: " + err);
        });
      },

      _getGoloLink: function(alert_name) {
        var match = bugRegex.exec(alert_name);
        if (match && goloRegex.exec(match[1])) {
          // match[1] is the bot id
          return getFileBugSVG(match[1]);
        }
        return null;
      },

      _dismissAlert: function() {
        this._post("dismiss", {"comment": this._commentText });
      },

      _snoozeAlert: function () {
        var until = new Date();
        until.setDate(until.getDate() + parseInt(this._snoozeDays));
        until.setHours(until.getHours() + parseInt(this._snoozeHours));
        until.setMinutes(until.getMinutes() + parseInt(this._snoozeMins));
        var params = {
          "comment": this._commentText,
          "until": Math.round(until.getTime() / 1000)
        };
        this._post("snooze", params);
      },

      _snoozeDialog: function() {
        this.$.snoozeDialog.toggle();
      },

      _unsnoozeAlert: function() {
        this._post("unsnooze", {"comment": this._commentText});
      },

      _addComment: function() {
        if (this._commentText == "") {
          sk.errorMessage("Empty comments are not allowed.");
          return;
        }
        this._post("addcomment", {"comment":this._commentText});
      },

      _preventBubble: function(e) {
        e.stopPropagation();
        return true;
      },
    });
  })()
  </script>
</dom-module>
