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

    <task-scheduler-blacklist-sk>

  Status information about the task scheduler.

  To use this file import it:

    <link href="/res/imp/task-scheduler-blacklist-sk.html" rel="import" />

  Usage:

    <task-scheduler-blacklist-sk></task-scheduler-blacklist-sk>

  Properties:
    // input
    rules: Array of Objects indicating the current set of blacklist rules:
        added_by: String, Who added the rule.
        task_spec_patterns: Array, regular expressions which match task_spec names.
        commits: Array, commit hashes
        description: String, detailed information about the rule.
        name: String, name of the rule.

  Methods:
    None.

  Events:
    None.
-->

<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-icons/iron-icons.html">
<link rel="import" href="/res/imp/bower_components/paper-button/paper-button.html">
<link rel="import" href="/res/imp/bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="/res/imp/bower_components/paper-fab/paper-fab.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">
<link rel="import" href="/res/imp/bower_components/paper-input/paper-textarea.html">
<link rel="import" href="/res/imp/bower_components/paper-spinner/paper-spinner.html">
<link rel="import" href="/res/common/imp/autocomplete-input-sk.html">
<link rel="import" href="/res/common/imp/human-date-sk.html">
<link rel="import" href="/res/common/imp/input-list-sk.html">

<dom-module id="task-scheduler-blacklist-sk">
  <template>
    <style include="iron-flex iron-flex-alignment">
    :host {
      font-family: sans-serif;
    }
    .task_spec_pattern, .commit {
      font-family: "Lucida Console", Monaco, monospace;
    }
    .container {
      margin: 5px;
      padding: 10px;
      border: 1px solid #eeeeee;
      font-size: 12px;
    }
    .container h2 {
      font-size: 16px;
    }
    #add_button {
      padding: 0.7em 0.57em;
      margin-top: 10px;
    }
    #input_pane {
      width: 400px;
    }
    #range_checkbox {
      margin-top: 18px;
    }
    paper-fab {
      background-color: #d23f31;
      margin: 25px;
      position: fixed;
      bottom: 20px;
      right: 20px;
    }
    .table {
      border-collapse: collapse;
      display: table;
    }
    .tr {
      border-bottom: 1px solid #EEEEEE;
      display: table-row;
    }
    .tr:hover {
      background-color: #F5F5F5;
    }
    .tr:hover .tr:hover {
      background-color: #FFFFFF;
    }
    .td,.th {
      display: table-cell;
      padding: 10px;
    }
    .td {
      color: #212121;
      font-size: 0.813em;
      vertical-align: middle;
    }
    .th {
      color: #767676;
      font-size: 0.75em;
    }
    </style>
    <div class="table" hidden$="{{_loading}}">
      <div class="tr">
        <div class="th"><!-- delete button--></div>
        <div class="th">Name</div>
        <div class="th">Added by</div>
        <div class="th">TaskSpec Patterns</div>
        <div class="th">Commits</div>
        <div class="th">Description</div>
      </div>
      <template is="dom-repeat" items="{{rules}}">
        <div class="tr">
          <div class="td">
            <paper-icon-button icon="delete" on-click="_remove_rule" value="{{item.name}}"></paper-icon-button>
          </div>
          <div class="td">{{item.name}}</div>
          <div class="td">{{item.added_by}}</div>
          <div class="td">
            <template is="dom-repeat" items="{{item.task_spec_patterns}}">
              <div class="task_spec_pattern">{{item}}</div>
            </template>
          </div>
          <div class="td">
            <template is="dom-repeat" items="{{item.commits}}">
              <div class="commit">{{item}}</div>
            </template>
          </div>
          <div class="td">{{item.description}}</div>
        </div>
      </template>
    </div>
    <paper-spinner active$="{{_loading}}"></paper-spinner>
    <paper-fab icon="add" on-click="_add_rule_popup"></paper-fab>
    <paper-dialog id="add_dialog">
      <h2>Add a blacklist rule</h2>
      <div class="layout horizontal">
        <div id="input_pane">
          <paper-input label="name" value="{{_input_name}}"></paper-input>
          <input-list-sk
              heading="task_spec patterns"
              values="{{_input_task_spec_patterns}}"
              ></input-list-sk>
          <div class="container">
            <h2>commit(s)</h2>
            <autocomplete-input-sk
                label="single commit or range start (oldest; inclusive)"
                value="{{_input_commit}}"
                accept-custom-value="true"
                ></autocomplete-input-sk>
            <paper-checkbox checked="{{_input_commit_is_range}}" id="range_checkbox">
              commit range?
            </paper-checkbox>
            <autocomplete-input-sk
                hidden$="{{!_input_commit_is_range}}"
                label="commit range end (newest; non-inclusive)"
                value="{{_input_commit_range_end}}"
                accept-custom-value="true"
                ></autocomplete-input-sk>
          </div>
          <paper-textarea label="description" value="{{_input_description}}" rows="5"></paper-textarea>
          <paper-button on-click="_add_rule" id="add_button" raised>Add Rule</paper-button>
        </div>
      </div>
    </paper-dialog>
  </template>
  <script>
  (function(){
    Polymer({
      is: "task-scheduler-blacklist-sk",

      properties: {
        rules: {
          type: Array,
        },

        _input_task_spec_patterns: {
          type: Array,
          value: function() {
            return [];
          },
        },

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

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

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

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

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

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

      _add_rule() {
        // Validate the form inputs.
        if (this._input_name == "") {
          sk.errorMessage("Rules must have a name.");
          return;
        } else if (this._input_name.length > 50) {
          sk.errorMessage("Rule names are 50 characters maximum. Use the 'description' field for detailed information.")
          return;
        }
        // Submit the new rule to the server.
        var data = {
          "task_spec_patterns": this._input_task_spec_patterns,
          "commits": [],
          "description": this._input_description,
          "name": this._input_name,
        };
        if (this._input_commit) {
          data["commits"].push(this._input_commit.trim());
        }
        if (this._input_commit_is_range) {
          data["commits"].push(this._input_commit_range_end.trim());
        }
        if (this._input_task_spec_patterns.length == 0 && data["commits"].length == 0) {
          sk.errorMessage("Rules must have at least one task_spec pattern and/or commit.")
          return;
        }
        var str = JSON.stringify(data);
        this._loading = true;
        this.$.add_dialog.close();
        sk.post("/json/blacklist", str).then(function(resp) {
          this._loading = false;
          var rules;
          try {
            rules = JSON.parse(resp).rules;
          } catch(e) {
            sk.errorMessage("Got invalid response from the server: " + e);
            return;
          }
          this.rules = [];
          for (var key in rules) {
            this.push("rules", rules[key]);
          }
          this._input_task_spec_patterns = [];
          this._input_commit = "";
          this._input_commit_is_range = false;
          this._input_commit_range_end = "";
          this._input_description = "";
          this._input_name = "";
        }.bind(this), function(err) {
          this._loading = false;
          this.$.add_dialog.open();
          sk.errorMessage(err);
        }.bind(this));
      },

      _add_rule_popup() {
        this.$.add_dialog.open();
      },

      _remove_rule(e) {
        var data = {
          "id": e.model.item.name,
        };
        var str = JSON.stringify(data);
        this._loading = true;
        sk.delete("/json/blacklist", str).then(function(resp) {
          this._loading = false;
          var rules;
          try {
            rules = JSON.parse(resp).rules;
          } catch(e) {
            sk.errorMessage("Got invalid response from the server: " + e);
            return;
          }
          this.rules = [];
          for (var key in rules) {
            this.push("rules", rules[key]);
          }
        }.bind(this), function(err) {
          this._loading = false;
          sk.errorMessage(err);
        }.bind(this));
      },
    });
  })();
  </script>
</dom-module>
