/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {LitElement, html, TemplateResult} from 'lit';
import {property} from 'lit/decorators.js';
import {styleMap} from 'lit/directives/style-map.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.
 */
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=${styleMap({'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;
  }
}

customElements.define('gr-diff-text', GrDiffText);

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