/**
 * @fileoverview A custom element that loads the CT pending tasks queue and
 * displays it as a table.
 */

import '../../../elements-sk/modules/icons/delete-icon-sk';
import '../../../elements-sk/modules/icons/cancel-icon-sk';
import '../../../elements-sk/modules/icons/check-circle-icon-sk';
import '../../../elements-sk/modules/icons/help-icon-sk';
import '../../../elements-sk/modules/toast-sk';

import { html } from 'lit-html';
import { $$, DomReady } from '../../../infra-sk/modules/dom';
import { fromObject } from '../../../infra-sk/modules/query';
import { jsonOrThrow } from '../../../infra-sk/modules/jsonOrThrow';
import { define } from '../../../elements-sk/modules/define';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';

import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import {
  getFormattedTimestamp,
  taskDescriptors,
  getTimestamp,
  getCtDbTimestamp,
  TaskDescriptor,
} from '../ctfe_utils';

import { CommonCols, DeleteTaskRequest, GetTasksResponse } from '../json';

function hideDialog(e: Event) {
  const classList = (e.target as HTMLElement).classList;
  if (classList.contains('dialog-background')) {
    classList.add('hidden');
  }
}

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

export class TaskQueueSk extends ElementSk {
  private _pendingTasks: CommonCols[] = [];

  private _running: boolean = false;

  constructor() {
    super(TaskQueueSk.template);
  }

  private static template = (el: TaskQueueSk) => html`
    <table class="runssummary surface-themes-sk secondary-links" id="queue">
      <tr>
        <th>Queue Position</th>
        <th>Added</th>
        <th>Task Type</th>
        <th>User</th>
        <th>Swarming Logs</th>
        <th>Request</th>
      </tr>
      ${el._pendingTasks.map((task: CommonCols, index: number) =>
        TaskQueueSk.taskRowTemplate(el, task, index)
      )}
    </table>
    ${el._pendingTasks.map((task, index) =>
      TaskQueueSk.taskDetailDialogTemplate(task, index)
    )}
    <toast-sk id="confirm_toast" duration="5000"></toast-sk>
  `;

  private static taskRowTemplate = (
    el: TaskQueueSk,
    task: CommonCols,
    index: number
  ) => html` <tr>
    <td class="nowrap">
      ${index + 1}
      <delete-icon-sk
        title="Delete this task"
        alt="Delete"
        ?hidden=${!task.can_delete}
        @click=${() => el.confirmDeleteTask(index)}></delete-icon-sk>
    </td>
    <td>
      ${getFormattedTimestamp(task.ts_added)}
      ${task.future_date
        ? html`</br><span class=error-themes-sk>(scheduled in the future)</span>`
        : ''}
    </td>
    <td>${task.task_type}</td>
    <td>${task.username}</td>
    <td class="nowrap">
      ${task.future_date
        ? html`N/A`
        : task.swarming_logs
        ? html`<a href="${task.swarming_logs}" rel="noopener" target="_blank"
            >Swarming Logs</a
          >`
        : html`No Swarming Logs`}
    </td>
    <td class="nowrap">
      <a href="#" class="details" @click=${() => el.showDetailsDialog(index)}
        >Task Details</a
      >
    </td>
  </tr>`;

  private static taskDetailDialogTemplate = (
    task: CommonCols,
    index: number
  ) => html`
    <div
      id=${`detailsDialog${index}`}
      class="dialog-background hidden overlay-themes-sk"
      @click=${hideDialog}>
      <div class="dialog-content surface-themes-sk">
        <pre>${formatTask(task)}</pre>
      </div>
    </div>
  `;

  connectedCallback(): void {
    super.connectedCallback();
    if (this._running) {
      return;
    }
    this._running = true;
    // We wait for everything to load so scaffolding event handlers are
    // attached.
    DomReady.then(() => {
      this.dispatchEvent(new CustomEvent('begin-task', { bubbles: true }));
      this._render();
      this.loadTaskQueue().then(() => {
        this._render();
        this._running = false;
        this.dispatchEvent(new CustomEvent('end-task', { bubbles: true }));
      });
    });
  }

  showDetailsDialog(index: number): void {
    ($$(`#detailsDialog${index}`, this) as HTMLElement).classList.remove(
      'hidden'
    );
  }

  // Dispatch requests to fetch tasks in queue. Returns a promise that resolves
  // when all task data fetching/updating is complete.
  loadTaskQueue(): Promise<void[]> {
    this._pendingTasks = [];
    // TODO(rmistry):
    // This should really use the task_common.QueryParams type and
    // the parameters should be POST'ed instead of sent via queryStr.
    const queryParams = {
      size: 100,
      not_completed: true,
      include_future_runs: false,
    };
    let queryStr = `?${fromObject(queryParams)}`;
    const allPromises = [];
    for (const obj of taskDescriptors) {
      allPromises.push(
        fetch(obj.get_url + queryStr, { method: 'POST' })
          .then(jsonOrThrow)
          .then((json) => {
            this.updatePendingTasks(json, obj);
          })
          .catch(errorMessage)
      );
    }

    // Find all tasks scheduled in the future.
    const futureQueryParams = {
      include_future_runs: true,
    };
    queryStr = `?${fromObject(futureQueryParams)}`;
    for (const obj of taskDescriptors) {
      allPromises.push(
        fetch(obj.get_url + queryStr, { method: 'POST' })
          .then(jsonOrThrow)
          .then((json) => {
            this.updatePendingTasks(json, obj);
          })
          .catch(errorMessage)
      );
    }
    return Promise.all(allPromises);
  }

  // Add responses to pending tasks list.
  updatePendingTasks(
    json: GetTasksResponse,
    taskDescriptor: TaskDescriptor
  ): void {
    const tasks = json.data;
    for (let i = 0; i < tasks.length; i++) {
      const task = tasks[i] as CommonCols;
      task.can_delete = json.permissions![i].DeleteAllowed;
      task.id = json.ids![i];
      task.task_type = taskDescriptor.type;
      task.get_url = taskDescriptor.get_url;
      task.delete_url = taskDescriptor.delete_url;
      // Check if this is a completed task set to repeat.
      if (task.repeat_after_days !== 0 && task.task_done) {
        // Calculate the future date.
        const timestamp = getTimestamp(task.ts_added);
        timestamp.setDate(timestamp.getDate() + task.repeat_after_days);
        task.future_date = true;
        task.ts_added = +getCtDbTimestamp(new Date(timestamp));
      }
    }
    this._pendingTasks = this._pendingTasks.concat(tasks);
    // Sort pending tasks according to TsAdded.
    this._pendingTasks.sort((a, b) => a.ts_added - b.ts_added);
  }

  confirmDeleteTask(index: number): void {
    const confirmed = window.confirm('Delete this task?');
    if (confirmed) {
      this.deleteTask(index);
    }
  }

  deleteTask(index: number): void {
    const pendingTask = this._pendingTasks[index];
    const params: DeleteTaskRequest = { id: pendingTask.id };
    // params.id = pendingTask.Id;
    fetch(pendingTask.delete_url, {
      method: 'POST',
      body: JSON.stringify(params),
    })
      .then((res) => {
        if (res.ok) {
          this._pendingTasks.splice(index, 1);
          window.alert(
            `Deleted ${pendingTask.task_type} task ${pendingTask.id}`
          );
          return;
        }
        // Non-OK status. Read the response and punt it to the catch.
        res.text().then((text) => {
          throw new Error(`Failed to delete the task: ${text}`);
        });
      })
      .then(() => {
        this._render();
      })
      .catch(errorMessage);
  }
}

define('task-queue-sk', TaskQueueSk);
