/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {LitElement, html, TemplateResult} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {diffClasses} from '../gr-diff/gr-diff-utils';

const SURROGATE_PAIR = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;

const TAB = '\t';

/**
 * Renders one line of code on one side of the diff. It takes care of:
 * - Tabs, see `tabSize` property.
 * - Line Breaks, see `lineLimit` property.
 * - Surrogate Character Pairs.
 *
 * Note that other modifications to the code in a gr-diff is done via diff
 * layers, which manipulate the DOM directly. So `gr-diff-text` is thrown
 * away and re-rendered every time something changes by its parent
 * `gr-diff-row`. So don't bother to optimize this component for re-rendering
 * performance. And be aware that building longer lived local state is not
 * useful here.
 */
@customElement('gr-diff-text')
export class GrDiffText extends LitElement {
  /**
   * The browser API for handling selection does not (yet) work for selection
   * across multiple shadow DOM elements. So we are rendering gr-diff components
   * into the light DOM instead of the shadow DOM by overriding this method,
   * which was the recommended workaround by the lit team.
   * See also https://github.com/WICG/webcomponents/issues/79.
   */
  override createRenderRoot() {
    return this;
  }

  @property({type: String})
  text = '';

  @property({type: Boolean})
  isResponsive = false;

  @property({type: Number})
  tabSize = 2;

  @property({type: Number})
  lineLimit = 80;

  /** Temporary state while rendering. */
  private textOffset = 0;

  /** Temporary state while rendering. */
  private columnPos = 0;

  /** Temporary state while rendering. */
  private pieces: (string | TemplateResult)[] = [];

  /** Split up the string into tabs, surrogate pairs and regular segments. */
  override render() {
    this.textOffset = 0;
    this.columnPos = 0;
    this.pieces = [];
    const splitByTab = this.text.split('\t');
    for (let i = 0; i < splitByTab.length; i++) {
      const splitBySurrogate = splitByTab[i].split(SURROGATE_PAIR);
      for (let j = 0; j < splitBySurrogate.length; j++) {
        this.renderSegment(splitBySurrogate[j]);
        if (j < splitBySurrogate.length - 1) {
          this.renderSurrogatePair();
        }
      }
      if (i < splitByTab.length - 1) {
        this.renderTab();
      }
    }
    if (this.textOffset !== this.text.length) throw new Error('unfinished');
    return this.pieces;
  }

  /** Render regular characters, but insert line breaks appropriately. */
  private renderSegment(segment: string) {
    let segmentOffset = 0;
    while (segmentOffset < segment.length) {
      const newOffset = Math.min(
        segment.length,
        segmentOffset + this.lineLimit - this.columnPos
      );
      this.renderString(segment.substring(segmentOffset, newOffset));
      segmentOffset = newOffset;
      if (segmentOffset < segment.length && this.columnPos === this.lineLimit) {
        this.renderLineBreak();
      }
    }
  }

  /** Render regular characters. */
  private renderString(s: string) {
    if (s.length === 0) return;
    this.pieces.push(s);
    this.textOffset += s.length;
    this.columnPos += s.length;
    if (this.columnPos > this.lineLimit) throw new Error('over line limit');
  }

  /** Render a tab character. */
  private renderTab() {
    let tabSize = this.tabSize - (this.columnPos % this.tabSize);
    if (this.columnPos + tabSize > this.lineLimit) {
      this.renderLineBreak();
      tabSize = this.tabSize;
    }
    const piece = html`<span
      class=${diffClasses('tab')}
      style="tab-size: ${tabSize}; -moz-tab-size: ${tabSize};"
      >${TAB}</span
    >`;
    this.pieces.push(piece);
    this.textOffset += 1;
    this.columnPos += tabSize;
  }

  /** Render a surrogate pair: string length is 2, but is just 1 char. */
  private renderSurrogatePair() {
    if (this.columnPos === this.lineLimit) {
      this.renderLineBreak();
    }
    this.pieces.push(this.text.substring(this.textOffset, this.textOffset + 2));
    this.textOffset += 2;
    this.columnPos += 1;
  }

  /** Render a line break, don't advance text offset, reset col position. */
  private renderLineBreak() {
    if (this.isResponsive) {
      this.pieces.push(html`<wbr class=${diffClasses()}></wbr>`);
    } else {
      this.pieces.push(html`<span class=${diffClasses('br')}></span>`);
    }
    // this.textOffset += 0;
    this.columnPos = 0;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-diff-text': GrDiffText;
  }
}
