<!--
  The <pending-tasks-sk> custom element declaration. Displays a table of tasks that are not yet
  completed, including popups with detailed information.

  Attributes:
    None.

  Events:
    None.

  Methods:
    None.
-->

<dom-module id="pending-tasks-sk">
  <style>
    paper-dialog {
      min-width: 200px;
      max-width: calc(100% - 10px);
    }
    table.queue {
      border-spacing: 0px;
      padding-top: 2em;
    }
    tr.headers {
      background-color: #CCCCFF;
      text-align: center;
    }
    td.nowrap {
      white-space: nowrap;
    }
    th,
    td  {
      padding: 15px;
      border: solid black 1px;
    }
    .delete-button {
      --paper-icon-button-disabled: {
        display: none;
      }
    }
  </style>
  <template>

    <confirm-dialog-sk id="confirm_dialog"></confirm-dialog-sk>

    <h2>Tasks in the Queue</h2>

    <!-- Section for popups. -->
    <template is="dom-repeat" items="{{pendingTasks}}" as="pendingTask" index-as="index">
      <paper-dialog heading="Task Details" id="{{ getTaskDetailsId(index) }}">
        <paper-dialog-scrollable>
          <pre>{{ formatTask(pendingTask) }}</pre>
        </paper-dialog-scrollable>
      </paper-dialog>
    </template>

    <table class="queue" id="queue">
      <tr class="headers">
        <td>Queue Position</td>
        <td>Added</td>
        <td>Task Type</td>
        <td>User</td>
        <td>Swarming Logs</td>
        <td>Request</td>
      </tr>

      <template is="dom-repeat" items="{{pendingTasks}}" as="pendingTask" index-as="index">
        <tr>
          <!-- Queue Position col -->
          <td class="nowrap">
            <span>{{ incrementOne(index) }}</span>
            <paper-icon-button icon="delete" mini
                               class="delete-button"
                               disabled="{{!pendingTask.canDelete}}"
                               alt="Delete"
                               data-index$="{{index}}"
                               data-type="delete">
            </paper-icon-button>
          </td>

          <!-- Added col -->
          <td>{{ formatTimestamp(pendingTask.TsAdded) }}
            <template is="dom-if" if="{{ pendingTask.FutureDate }}">
              <br/>
              <div style="color:red;">(scheduled in the future)</div>
            </template>
          </td>

          <!-- Task Type col -->
          <td>{{pendingTask.TaskType}}</td>

          <!-- User col -->
          <td>{{pendingTask.Username}}</td>

          <!-- Swarming logs col -->
          <td class="nowrap">
            <template is="dom-if" if="{{ pendingTask.FutureDate }}">
              N/A
            </template>
            <template is="dom-if" if="{{ !pendingTask.FutureDate }}">
              <template is="dom-if" if="{{ pendingTask.SwarmingLogs }}">
                <a href="{{ pendingTask.SwarmingLogs }}" target="_blank">Swarming Logs</a>
              </template>
            </template>
          </td>

          <!-- Request col -->
          <td class="nowrap">
            <a href="javascript:void(0);" data-id$="{{index}}">Task Details</a>
          </td>
        </tr>
      </template>
    </table>
  </template>
</dom-module>

<script>
   Polymer({
     is: "pending-tasks-sk",
     properties: {
       pendingTasks: {
         type: Array,
         value: [],
       },
       taskDescriptors: {
         type: Array,
         value: function() {
           return [{type: "ChromiumPerf",
                    get_url: "/_/get_chromium_perf_tasks",
                    delete_url: "/_/delete_chromium_perf_task"},
                   {type: "ChromiumAnalysis",
                    get_url: "/_/get_chromium_analysis_tasks",
                    delete_url: "/_/delete_chromium_analysis_task"},
                   {type: "MetricsAnalysis",
                    get_url: "/_/get_metrics_analysis_tasks",
                    delete_url: "/_/delete_metrics_analysis_task"},
                   {type: "CaptureSkps",
                    get_url: "/_/get_capture_skp_tasks",
                    delete_url: "/_/delete_capture_skps_task"},
                   {type: "ChromiumBuild",
                    get_url: "/_/get_chromium_build_tasks",
                    delete_url: "/_/delete_chromium_build_task"},
                   {type: "RecreatePageSets",
                    get_url: "/_/get_recreate_page_sets_tasks",
                    delete_url: "/_/delete_recreate_page_sets_task"},
                   {type: "RecreateWebpageArchives",
                    get_url: "/_/get_recreate_webpage_archives_tasks",
                    delete_url: "/_/delete_recreate_webpage_archives_task"},
                  ];
         }
       },
     },

     ready: function() {
       this.reload();

       this.$.queue.addEventListener('click', function(e) {
         var anchor = sk.findParent(e.target, "A");
         if (anchor != null) {
           var index = anchor.dataset.id;
           this.toggleDialog(this.getTaskDetailsId(index));
         }
       }.bind(this));

       this.$.queue.addEventListener('click', function(e) {
         var button = sk.findParent(e.target, "PAPER-ICON-BUTTON");
         if (button != null && button.dataset.type == "delete") {
           var index = button.dataset.index;
           this.$.confirm_dialog.open("Proceed with deleting task?")
               .then(this.deleteTask.bind(this, index));
         }
       }.bind(this));
     },

     reload: function() {
       this.pendingTasks = []
       var queryParams = {
         "size": 100,
         "not_completed": true,
       }
       var queryStr = "?" + sk.query.fromObject(queryParams);
       this.taskDescriptors.forEach(function(obj) {
         sk.post(obj.get_url + queryStr).then(JSON.parse).then(function(json) {
           this.updatePendingTasks(json, obj);
         }.bind(this)).catch(sk.errorMessage);
       }.bind(this));

       // Find all tasks scheduled in the future.
       var queryParams = {"include_future_runs": true,}
       var queryStr = "?" + sk.query.fromObject(queryParams);
       this.taskDescriptors.forEach(function(obj) {
         sk.post(obj.get_url + queryStr).then(JSON.parse).then(function(json) {
           this.updatePendingTasks(json, obj);
         }.bind(this)).catch(sk.errorMessage);
       }.bind(this));
     },

     incrementOne: function(index) {
       return index + 1;
     },

     getTaskDetailsId: function(index) {
       return "task_details" + index;
     },

     formatTask: function(task) {
       return JSON.stringify(task, null, 4);
     },

     updatePendingTasks: function(json, taskDescriptor) {
       var tasks = json.data
       for (index in tasks) {
         var task = tasks[index];
         task["canDelete"] = json.permissions[index].DeleteAllowed;
         task["Id"] = json.ids[index];
         task["TaskType"] = taskDescriptor.type;
         task["GetURL"] = taskDescriptor.get_url;
         task["DeleteURL"] = taskDescriptor.delete_url;
         // Check if this is a completed task set to repeat.
         if (task["RepeatAfterDays"] != 0 && task["TaskDone"]) {
           // Calculate the future date.
           var timestamp = ctfe.getTimestamp(task["TsAdded"]);
           timestamp.setDate(timestamp.getDate() + task["RepeatAfterDays"]);
           task["FutureDate"] = true;
           task["TsAdded"] = ctfe.getCtDbTimestamp(new Date(timestamp));
         }
       }
       this.pendingTasks = this.pendingTasks.concat(tasks)
       // Sort pending tasks according to TsAdded.
       this.pendingTasks.sort(function(a, b){return a["TsAdded"] - b["TsAdded"]});
     },

     deleteTask: function(deleteIndex) {
       var pendingTask = this.pendingTasks[deleteIndex];
       var params = {};
       params["id"] = pendingTask.Id;
       sk.post(pendingTask.DeleteURL, JSON.stringify(params)).then(function() {
         $$$("#confirm_toast").text = "Deleted " + pendingTask.TaskType + " task " + pendingTask.Id;
         $$$("#confirm_toast").show();
       }.bind(this)).catch(sk.errorMessage).then(function() {
         this.reload();
       }.bind(this));
     },

     toggleDialog: function(id) {
       Polymer.dom(this.root).querySelector('#' + id).toggle();
     },

     formatTimestamp: ctfe.getFormattedTimestamp,
  });
</script>
