/**
 * @module modules/task-graph-sk
 * @description <h2><code>task-graph-sk</code></h2>
 *
 * Displays a graph which shows the relationship between a set of tasks.
 */

import { render, svg } from 'lit-html';
import { define } from '../../../elements-sk/modules/define';

import {
  Job,
  Task,
  TaskDependencies,
  TaskDimensions,
  TaskSummaries,
  TaskSummary,
} from '../rpc';

type TaskName = string;

export class TaskGraphSk extends HTMLElement {
  draw(jobs: Job[], swarmingServer: string, selectedTask?: Task) {
    const graph: Map<TaskName, TaskName[]> = new Map();
    const taskData: Map<TaskName, TaskSummary[]> = new Map();
    const taskDims: Map<TaskName, string[]> = new Map();
    jobs.forEach((job: Job) => {
      job.dependencies?.forEach((dep: TaskDependencies) => {
        if (!graph.get(dep.task)) {
          graph.set(dep.task, dep.dependencies || []);
        }
      });
      job.taskDimensions?.forEach((dims: TaskDimensions) => {
        if (!taskDims.has(dims.taskName)) {
          taskDims.set(dims.taskName, dims.dimensions!);
        }
      });
      job.tasks?.forEach((taskSummaries: TaskSummaries) => {
        const tasks = taskData.get(taskSummaries.name) || [];
        taskSummaries.tasks?.forEach((task: TaskSummary) => {
          if (!tasks.find((item) => item.id === task.id)) {
            tasks.push(task);
          }
        });
        taskData.set(taskSummaries.name, tasks);
      });
    });

    // Sort the tasks and task specs for consistency.
    graph.forEach((tasks: string[]) => {
      tasks.sort();
    });
    taskData.forEach((tasks: TaskSummary[]) => {
      tasks.sort((a: TaskSummary, b: TaskSummary) => a.attempt - b.attempt);
    });

    // Compute the "depth" of each task spec.
    interface cell {
      name: string;
      tasks: TaskSummary[];
    }
    const depth: Map<TaskName, number> = new Map();
    const cols: cell[][] = [];
    const visited: Map<string, boolean> = new Map();

    const visit = function(current: string) {
      visited.set(current, true);
      let myDepth = 0;
      (graph.get(current) || []).forEach((dep: string) => {
        // Visit the dep if we haven't yet. Its depth may be zero, so we have
        // to explicitly use "depth[dep] == undefined" instead of "!depth[dep]"
        if (!visited.get(dep)) {
          visit(dep);
        }
        if ((depth.get(dep) || 0) >= myDepth) {
          myDepth = (depth.get(dep) || 0) + 1;
        }
      });
      depth.set(current, myDepth);
      if (cols.length == myDepth) {
        cols.push([]);
      } else if (myDepth > cols.length) {
        console.log('_computeTasksGraph skipped a column!');
        return;
      }
      cols[myDepth].push({
        name: current,
        tasks: taskData.get(current) || [],
      });
    };

    // Visit all of the nodes.
    graph.forEach((_: string[], key: string) => {
      if (!visited.get(key)) {
        visit(key);
      }
    });

    const arrowWidth = 4;
    const arrowHeight = 4;
    const botLinkFontSize = 11;
    const botLinkMarginX = 10;
    const botLinkMarginY = 4;
    const botLinkHeight = botLinkFontSize + 2 * botLinkMarginY;
    const botLinkText = 'view swarming bots';
    const fontFamily = 'Arial';
    const fontSize = 12;
    const taskSpecMarginX = 20;
    const taskSpecMarginY = 20;
    const taskMarginX = 10;
    const taskMarginY = 10;
    const textMarginX = 10;
    const textMarginY = 10;
    const taskWidth = 30;
    const taskHeight = 30;
    const taskLinkFontSize = botLinkFontSize;
    const taskLinkMarginX = botLinkMarginX;
    const taskLinkMarginY = botLinkMarginY;
    const taskLinkHeight = taskLinkFontSize + 2 * taskLinkMarginY;
    const taskLinkText = 'view swarming tasks';
    const textOffsetX = textMarginX;
    const textOffsetY = fontSize + textMarginY;
    const textHeight = fontSize + 2 * textMarginY;
    const botLinkOffsetY = textOffsetY + botLinkFontSize + botLinkMarginY;
    const taskLinkOffsetY = botLinkOffsetY + taskLinkFontSize + taskLinkMarginY;
    const taskSpecHeight = textHeight + botLinkHeight + taskLinkHeight + taskHeight + taskMarginY;

    // Compute the task spec block width for each column.
    const maxTextWidth = 0;
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d')!;
    ctx.font = `${botLinkFontSize}px ${fontFamily}`;
    const botLinkTextWidth = ctx.measureText(botLinkText).width + 2 * botLinkMarginX;
    ctx.font = `${taskLinkFontSize}px ${fontFamily}`;
    const taskLinkTextWidth = ctx.measureText(taskLinkText).width + 2 * taskLinkMarginX;
    ctx.font = `${fontSize}px ${fontFamily}`;
    const taskSpecWidth: number[] = [];
    cols.forEach((col: cell[]) => {
      // Get the minimum width of a task spec block needed to fit the entire
      // task spec name.
      let maxWidth = Math.max(botLinkTextWidth, taskLinkTextWidth);
      for (let i = 0; i < col.length; i++) {
        const oldFont = ctx.font;
        const text = col[i].name;
        if (text == selectedTask?.taskKey?.name) {
          ctx.font = `bold ${ctx.font}`;
        }
        const textWidth = ctx.measureText(text).width + 2 * textMarginX;
        ctx.font = oldFont;
        if (textWidth > maxWidth) {
          maxWidth = textWidth;
        }

        const numTasks = col[i].tasks.length || 1;
        const tasksWidth = taskMarginX + numTasks * (taskWidth + taskMarginX);
        if (tasksWidth > maxWidth) {
          maxWidth = tasksWidth;
        }
      }
      taskSpecWidth.push(maxWidth);
    });

    // Lay out the task specs and tasks.
    interface taskSpecRect {
      x: number;
      y: number;
      width: number;
      height: number;
      name: string;
      numTasks: number;
    }
    interface taskRect {
      x: number;
      y: number;
      width: number;
      height: number;
      task: TaskSummary;
    }
    let totalWidth = 0;
    let totalHeight = 0;
    const taskSpecs: taskSpecRect[] = [];
    const tasks: taskRect[] = [];
    const byName: Map<string, taskSpecRect> = new Map();
    let curX = taskMarginX;
    cols.forEach((col: cell[], colIdx: number) => {
      let curY = taskMarginY;
      // Add an entry for each task.
      col.forEach((taskSpec: cell) => {
        const entry: taskSpecRect = {
          x: curX,
          y: curY,
          width: taskSpecWidth[colIdx],
          height: taskSpecHeight,
          name: taskSpec.name,
          numTasks: taskSpec.tasks.length,
        };
        taskSpecs.push(entry);
        byName.set(taskSpec.name, entry);

        const taskX = curX + taskMarginX;
        const taskY = curY + textHeight + botLinkHeight + taskLinkHeight;
        taskSpec.tasks.forEach((task: TaskSummary, taskIdx: number) => {
          tasks.push({
            x: taskX + taskIdx * (taskWidth + taskMarginX),
            y: taskY,
            width: taskWidth,
            height: taskHeight,
            task: task,
          });
        });
        curY += taskSpecHeight + taskSpecMarginY;
      });
      if (curY > totalHeight) {
        totalHeight = curY;
      }
      curX += taskSpecWidth[colIdx] + taskSpecMarginX;
    });

    totalWidth = curX;

    // Compute the arrows.
    const arrows: string[] = [];
    graph.forEach((deps: string[], name: TaskName) => {
      const dst = byName.get(name)!;
      if (deps) {
        deps.forEach((dep: string) => {
          const src = byName.get(dep);
          if (!src) {
            console.log(
              `Error: task ${dst.name} has unknown parent ${dep}`,
            );
            return '';
          }
          // Start and end points.
          const x1 = src.x + src.width;
          const y1 = src.y + src.height / 2;
          const x2 = dst.x - arrowWidth;
          const y2 = dst.y + dst.height / 2;
          // Control points.
          const cx1 = x1 + taskSpecMarginX - arrowWidth / 2;
          const cy1 = y1;
          const cx2 = x2 - taskSpecMarginX + arrowWidth / 2;
          const cy2 = y2;
          arrows.push(
            `M${
              x1
            } ${
              y1
            } C${
              cx1
            } ${
              cy1
            } ${
              cx2
            } ${
              cy2
            } ${
              x2
            } ${
              y2}`,
          );
        });
      }
    });

    const taskStatusToClass: { [key: string]: string } = {
      TASK_STATUS_PENDING: 'bg-in-progress',
      TASK_STATUS_RUNNING: 'bg-in-progress',
      TASK_STATUS_SUCCESS: 'bg-success',
      TASK_STATUS_FAILURE: 'bg-failure',
      TASK_STATUS_MISHAP: 'bg-mishap',
    };

    // Draw the graph.
    render(
      svg`
      <svg width="${totalWidth}" height="${totalHeight}">
        <marker
            id="arrowhead"
            class="arrowhead"
            viewBox="0 0 10 10"
            refX="0"
            refY="5"
            markerUnits="strokeWidth"
            markerWidth="${arrowWidth}"
            markerHeight="${arrowHeight}"
            orient="auto"
            >
          <path d="M 0 0 L 10 5 L 0 10 Z"></path>
        </marker>
        ${arrows.map((arrow: string) => svg`
            <path
                class="arrow"
                marker-end="url(#arrowhead)"
                d="${arrow}"
                >
            </path>
          `)}
        ${taskSpecs.map(
    (taskSpec: taskSpecRect) => svg`
          <rect
              rx="4"
              ry="4"
              x="${taskSpec.x}"
              y="${taskSpec.y}"
              width="${taskSpec.width}"
              height="${taskSpec.height}"
              class="${
  taskSpec.name == selectedTask?.taskKey?.name ? 'emphasis' : ''
}"
              >
          </rect>
          <text
              x="${taskSpec.x + textOffsetX}"
              y="${taskSpec.y + textOffsetY}"
              class="${
  taskSpec.name == selectedTask?.taskKey?.name ? 'emphasis' : ''
}"
              >
            ${taskSpec.name}
          </text>
          <a
              target="_blank"
              href="${TaskGraphSk.computeBotsLink(
                taskDims.get(taskSpec.name)!,
                swarmingServer,
  )}">
            <text
                class="links"
                x="${taskSpec.x + textOffsetX}"
                y="${taskSpec.y + botLinkOffsetY}"
                >
              ${botLinkText}
            </text>
          </a>
          <a
              target="_blank"
              href="${TaskGraphSk.computeTasksLink(
    taskSpec.name,
    swarmingServer,
  )}">
            <text
                class="links"
                x="${taskSpec.x + textOffsetX}"
                y="${taskSpec.y + taskLinkOffsetY}"
                >
              ${taskLinkText}
            </text>
          </a>
        `,
  )}
        ${tasks.map(
    (task) => svg`
          <a
              class="task"
              target="_blank"
              href="${TaskGraphSk.computeTaskLink(task.task!, swarmingServer)}">
            <rect
                class="task ${
  task.task.id == selectedTask?.id ? 'emphasis' : ''
} ${taskStatusToClass[task.task!.status]}"
                rx="4"
                ry="4"
                x="${task.x}"
                y="${task.y}"
                width="${task.width}"
                height="${task.height}"
                >
            </rect>
          </a>
        `,
  )}
      </svg>
    `,
      this,
    );
  }

  private static computeBotsLink(
    dims: string[],
    swarmingServer: string,
  ): string {
    let link = `https://${swarmingServer}/botlist`;
    if (dims) {
      for (let i = 0; i < dims.length; i++) {
        if (i == 0) {
          link += '?';
        } else {
          link += '&';
        }
        link += `f=${encodeURIComponent(dims[i])}`;
      }
    }
    return link;
  }

  private static computeTaskLink(
    task: TaskSummary,
    swarmingServer: string,
  ): string {
    const swarmingLink = `https://${swarmingServer}/task?id=${task.swarmingTaskId}`;
    return (
      `https://task-driver.skia.org/td/${
        task.id
      }?ifNotFound=${
        encodeURIComponent(swarmingLink)}`
    );
  }

  private static computeTasksLink(
    name: string,
    swarmingServer: string,
  ): string {
    return `https://${swarmingServer}/tasklist?f=sk_name-tag:${name}`;
  }
}

define('task-graph-sk', TaskGraphSk);
