/**
 * @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);
