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

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

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

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);
