/**
 * @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, isNewDiff} 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;
  }
}

// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
if (!isNewDiff()) {
  customElements.define('gr-diff-text', GrDiffText);
}

declare global {
  interface HTMLElementTagNameMap {
    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
    'gr-diff-text': LitElement;
  }
}
