// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

interface PR {
  prettyPrint(_: unknown, el: HTMLElement): void;
}

declare global {
  const PR: PR;
}

import { Source, SourceResolver, sourcePositionToStringKey } from "../src/source-resolver";
import { SelectionBroker } from "../src/selection-broker";
import { View } from "../src/view";
import { MySelection } from "../src/selection";
import { ViewElements } from "../src/util";
import { SelectionHandler } from "./selection-handler";

export enum CodeMode {
  MAIN_SOURCE = "main function",
  INLINED_SOURCE = "inlined function"
}

export class CodeView extends View {
  broker: SelectionBroker;
  source: Source;
  sourceResolver: SourceResolver;
  codeMode: CodeMode;
  sourcePositionToHtmlElement: Map<string, HTMLElement>;
  showAdditionalInliningPosition: boolean;
  selectionHandler: SelectionHandler;
  selection: MySelection;

  createViewElement() {
    const sourceContainer = document.createElement("div");
    sourceContainer.classList.add("source-container");
    return sourceContainer;
  }

  constructor(parent: HTMLElement, broker: SelectionBroker, sourceResolver: SourceResolver, sourceFunction: Source, codeMode: CodeMode) {
    super(parent);
    const view = this;
    view.broker = broker;
    view.sourceResolver = sourceResolver;
    view.source = sourceFunction;
    view.codeMode = codeMode;
    this.sourcePositionToHtmlElement = new Map();
    this.showAdditionalInliningPosition = false;

    const selectionHandler = {
      clear: function () {
        view.selection.clear();
        view.updateSelection();
        broker.broadcastClear(this);
      },
      select: function (sourcePositions, selected) {
        const locations = [];
        for (const sourcePosition of sourcePositions) {
          locations.push(sourcePosition);
          sourceResolver.addInliningPositions(sourcePosition, locations);
        }
        if (locations.length == 0) return;
        view.selection.select(locations, selected);
        view.updateSelection();
        broker.broadcastSourcePositionSelect(this, locations, selected);
      },
      brokeredSourcePositionSelect: function (locations, selected) {
        const firstSelect = view.selection.isEmpty();
        for (const location of locations) {
          const translated = sourceResolver.translateToSourceId(view.source.sourceId, location);
          if (!translated) continue;
          view.selection.select([translated], selected);
        }
        view.updateSelection(firstSelect);
      },
      brokeredClear: function () {
        view.selection.clear();
        view.updateSelection();
      },
    };
    view.selection = new MySelection(sourcePositionToStringKey);
    broker.addSourcePositionHandler(selectionHandler);
    this.selectionHandler = selectionHandler;
    this.initializeCode();
  }

  addHtmlElementToSourcePosition(sourcePosition, element) {
    const key = sourcePositionToStringKey(sourcePosition);
    if (this.sourcePositionToHtmlElement.has(key)) {
      console.log("Warning: duplicate source position", sourcePosition);
    }
    this.sourcePositionToHtmlElement.set(key, element);
  }

  getHtmlElementForSourcePosition(sourcePosition) {
    const key = sourcePositionToStringKey(sourcePosition);
    return this.sourcePositionToHtmlElement.get(key);
  }

  updateSelection(scrollIntoView: boolean = false): void {
    const mkVisible = new ViewElements(this.divNode.parentNode as HTMLElement);
    for (const [sp, el] of this.sourcePositionToHtmlElement.entries()) {
      const isSelected = this.selection.isKeySelected(sp);
      mkVisible.consider(el, isSelected);
      el.classList.toggle("selected", isSelected);
    }
    mkVisible.apply(scrollIntoView);
  }

  getCodeHtmlElementName() {
    return `source-pre-${this.source.sourceId}`;
  }

  getCodeHeaderHtmlElementName() {
    return `source-pre-${this.source.sourceId}-header`;
  }

  getHtmlCodeLines(): NodeListOf<HTMLElement> {
    const ordereList = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`);
    return ordereList.childNodes as NodeListOf<HTMLElement>;
  }

  onSelectLine(lineNumber: number, doClear: boolean) {
    if (doClear) {
      this.selectionHandler.clear();
    }
    const positions = this.sourceResolver.linetoSourcePositions(lineNumber - 1);
    if (positions !== undefined) {
      this.selectionHandler.select(positions, undefined);
    }
  }

  onSelectSourcePosition(sourcePosition, doClear: boolean) {
    if (doClear) {
      this.selectionHandler.clear();
    }
    this.selectionHandler.select([sourcePosition], undefined);
  }

  initializeCode() {
    const view = this;
    const source = this.source;
    const sourceText = source.sourceText;
    if (!sourceText) return;
    const sourceContainer = view.divNode;
    if (this.codeMode == CodeMode.MAIN_SOURCE) {
      sourceContainer.classList.add("main-source");
    } else {
      sourceContainer.classList.add("inlined-source");
    }
    const codeHeader = document.createElement("div");
    codeHeader.setAttribute("id", this.getCodeHeaderHtmlElementName());
    codeHeader.classList.add("code-header");
    const codeFileFunction = document.createElement("div");
    codeFileFunction.classList.add("code-file-function");
    codeFileFunction.innerHTML = `${source.sourceName}:${source.functionName}`;
    codeHeader.appendChild(codeFileFunction);
    const codeModeDiv = document.createElement("div");
    codeModeDiv.classList.add("code-mode");
    codeModeDiv.innerHTML = `${this.codeMode}`;
    codeHeader.appendChild(codeModeDiv);
    const clearDiv = document.createElement("div");
    clearDiv.style.clear = "both";
    codeHeader.appendChild(clearDiv);
    sourceContainer.appendChild(codeHeader);
    const codePre = document.createElement("pre");
    codePre.setAttribute("id", this.getCodeHtmlElementName());
    codePre.classList.add("prettyprint");
    sourceContainer.appendChild(codePre);

    codeHeader.onclick = function myFunction() {
      if (codePre.style.display === "none") {
        codePre.style.display = "block";
      } else {
        codePre.style.display = "none";
      }
    };
    if (sourceText != "") {
      codePre.classList.add("linenums");
      codePre.textContent = sourceText;
      try {
        // Wrap in try to work when offline.
        PR.prettyPrint(undefined, sourceContainer);
      } catch (e) {
        console.log(e);
      }

      view.divNode.onclick = function (e: MouseEvent) {
        if (e.target instanceof Element && e.target.tagName == "DIV") {
          const targetDiv = e.target as HTMLDivElement;
          if (targetDiv.classList.contains("line-number")) {
            e.stopPropagation();
            view.onSelectLine(Number(targetDiv.dataset.lineNumber), !e.shiftKey);
          }
        } else {
          view.selectionHandler.clear();
        }
      };

      const base: number = source.startPosition;
      let current = 0;
      const lineListDiv = this.getHtmlCodeLines();
      let newlineAdjust = 0;
      for (let i = 0; i < lineListDiv.length; i++) {
        // Line numbers are not zero-based.
        const lineNumber = i + 1;
        const currentLineElement = lineListDiv[i];
        currentLineElement.id = "li" + i;
        currentLineElement.dataset.lineNumber = "" + lineNumber;
        const spans = currentLineElement.childNodes;
        for (const currentSpan of spans) {
          if (currentSpan instanceof HTMLSpanElement) {
            const pos = base + current;
            const end = pos + currentSpan.textContent.length;
            current += currentSpan.textContent.length;
            this.insertSourcePositions(currentSpan, lineNumber, pos, end, newlineAdjust);
            newlineAdjust = 0;
          }
        }

        this.insertLineNumber(currentLineElement, lineNumber);

        while ((current < sourceText.length) &&
          (sourceText[current] == '\n' || sourceText[current] == '\r')) {
          ++current;
          ++newlineAdjust;
        }
      }
    }
  }

  insertSourcePositions(currentSpan, lineNumber, pos, end, adjust) {
    const view = this;
    const sps = this.sourceResolver.sourcePositionsInRange(this.source.sourceId, pos - adjust, end);
    let offset = 0;
    for (const sourcePosition of sps) {
      this.sourceResolver.addAnyPositionToLine(lineNumber, sourcePosition);
      const textnode = currentSpan.tagName == 'SPAN' ? currentSpan.lastChild : currentSpan;
      if (!(textnode instanceof Text)) continue;
      const splitLength = Math.max(0, sourcePosition.scriptOffset - pos - offset);
      offset += splitLength;
      const replacementNode = textnode.splitText(splitLength);
      const span = document.createElement('span');
      span.setAttribute("scriptOffset", sourcePosition.scriptOffset);
      span.classList.add("source-position");
      const marker = document.createElement('span');
      marker.classList.add("marker");
      span.appendChild(marker);
      const inlining = this.sourceResolver.getInliningForPosition(sourcePosition);
      if (inlining != undefined && view.showAdditionalInliningPosition) {
        const sourceName = this.sourceResolver.getSourceName(inlining.sourceId);
        const inliningMarker = document.createElement('span');
        inliningMarker.classList.add("inlining-marker");
        inliningMarker.setAttribute("data-descr", `${sourceName} was inlined here`);
        span.appendChild(inliningMarker);
      }
      span.onclick = function (e) {
        e.stopPropagation();
        view.onSelectSourcePosition(sourcePosition, !e.shiftKey);
      };
      view.addHtmlElementToSourcePosition(sourcePosition, span);
      textnode.parentNode.insertBefore(span, replacementNode);
    }
  }

  insertLineNumber(lineElement: HTMLElement, lineNumber: number) {
    const view = this;
    const lineNumberElement = document.createElement("div");
    lineNumberElement.classList.add("line-number");
    lineNumberElement.dataset.lineNumber = `${lineNumber}`;
    lineNumberElement.innerText = `${lineNumber}`;
    lineElement.insertBefore(lineNumberElement, lineElement.firstChild);
    // Don't add lines to source positions of not in backwardsCompatibility mode.
    if (this.source.backwardsCompatibility === true) {
      for (const sourcePosition of this.sourceResolver.linetoSourcePositions(lineNumber - 1)) {
        view.addHtmlElementToSourcePosition(sourcePosition, lineElement);
      }
    }
  }

}
