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