/**
 * @license
 * Copyright 2015 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../styles/shared-styles';
import '../../../elements/shared/gr-button/gr-button';
import '../../../elements/shared/gr-icon/gr-icon';
import '../gr-diff-builder/gr-diff-builder-element';
import '../gr-diff-highlight/gr-diff-highlight';
import '../gr-diff-selection/gr-diff-selection';
import '../gr-syntax-themes/gr-syntax-theme';
import '../gr-ranged-comment-themes/gr-ranged-comment-theme';
import '../gr-ranged-comment-hint/gr-ranged-comment-hint';
import {LineNumber} from './gr-diff-line';
import {
  getLine,
  getLineElByChild,
  getLineNumber,
  getRange,
  getSide,
  GrDiffThreadElement,
  isLongCommentRange,
  isThreadEl,
  rangesEqual,
  getResponsiveMode,
  isResponsive,
  getDiffLength,
} from './gr-diff-utils';
import {BlameInfo, CommentRange, ImageInfo} from '../../../types/common';
import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
import {
  CreateRangeCommentEventDetail,
  GrDiffHighlight,
} from '../gr-diff-highlight/gr-diff-highlight';
import {
  GrDiffBuilderElement,
  getLineNumberCellWidth,
} from '../gr-diff-builder/gr-diff-builder-element';
import {CoverageRange, DiffLayer} from '../../../types/types';
import {CommentRangeLayer} from '../gr-ranged-comment-layer/gr-ranged-comment-layer';
import {
  createDefaultDiffPrefs,
  DiffViewMode,
  Side,
} from '../../../constants/constants';
import {KeyLocations} from '../gr-diff-processor/gr-diff-processor';
import {fire, fireAlert} from '../../../utils/event-util';
import {MovedLinkClickedEvent, ValueChangedEvent} from '../../../types/events';
import {getContentEditableRange} from '../../../utils/safari-selection-util';
import {AbortStop} from '../../../api/core';
import {
  CreateCommentEventDetail as CreateCommentEventDetailApi,
  RenderPreferences,
  GrDiff as GrDiffApi,
  DisplayLine,
} from '../../../api/diff';
import {isSafari, toggleClass} from '../../../utils/dom-util';
import {assertIsDefined} from '../../../utils/common-util';
import {
  debounceP,
  DelayedPromise,
  DELAYED_CANCELLATION,
} from '../../../utils/async-util';
import {GrDiffSelection} from '../gr-diff-selection/gr-diff-selection';
import {customElement, property, query, state} from 'lit/decorators.js';
import {sharedStyles} from '../../../styles/shared-styles';
import {css, html, LitElement, nothing, PropertyValues} from 'lit';
import {when} from 'lit/directives/when.js';
import {grSyntaxTheme} from '../gr-syntax-themes/gr-syntax-theme';
import {grRangedCommentTheme} from '../gr-ranged-comment-themes/gr-ranged-comment-theme';
import {classMap} from 'lit/directives/class-map.js';
import {iconStyles} from '../../../styles/gr-icon-styles';
import {expandFileMode} from '../../../utils/file-util';
import {DiffModel, diffModelToken} from '../gr-diff-model/gr-diff-model';
import {provide} from '../../../models/dependency';

const NO_NEWLINE_LEFT = 'No newline at end of left file.';
const NO_NEWLINE_RIGHT = 'No newline at end of right file.';

const LARGE_DIFF_THRESHOLD_LINES = 10000;
const FULL_CONTEXT = -1;

const COMMIT_MSG_PATH = '/COMMIT_MSG';
/**
 * 72 is the unofficial length standard for git commit messages.
 * Derived from the fact that git log/show appends 4 ws in the beginning of
 * each line when displaying commit messages. To center the commit message
 * in an 80 char terminal a 4 ws border is added to the rightmost side:
 * 4 + 72 + 4
 */
const COMMIT_MSG_LINE_LENGTH = 72;

export interface CreateCommentEventDetail extends CreateCommentEventDetailApi {
  path: string;
}

@customElement('gr-diff')
export class GrDiff extends LitElement implements GrDiffApi {
  /**
   * Fired when the user selects a line.
   *
   * @event line-selected
   */

  /**
   * Fired if being logged in is required.
   *
   * @event show-auth-required
   */

  /**
   * Fired when a comment is created
   *
   * @event create-comment
   */

  /**
   * Fired when rendering, including syntax highlighting, is done. Also fired
   * when no rendering can be done because required preferences are not set.
   *
   * @event render
   */

  /**
   * Fired for interaction reporting when a diff context is expanded.
   * Contains an event.detail with numLines about the number of lines that
   * were expanded.
   *
   * @event diff-context-expanded
   */

  @query('#diffTable')
  diffTable?: HTMLTableElement;

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

  @property({type: String})
  path?: string;

  @property({type: Object})
  prefs?: DiffPreferencesInfo;

  @property({type: Object})
  renderPrefs: RenderPreferences = {};

  @property({type: Boolean})
  isImageDiff?: boolean;

  @property({type: Boolean, reflect: true})
  override hidden = false;

  @property({type: Boolean})
  noRenderOnPrefsChange?: boolean;

  // Private but used in tests.
  @state()
  commentRanges: CommentRangeLayer[] = [];

  // explicitly highlight a range if it is not associated with any comment
  @property({type: Object})
  highlightRange?: CommentRange;

  @property({type: Array})
  coverageRanges: CoverageRange[] = [];

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

  @property({type: String})
  viewMode = DiffViewMode.SIDE_BY_SIDE;

  @property({type: Object})
  lineOfInterest?: DisplayLine;

  /**
   * True when diff is changed, until the content is done rendering.
   * Use getter/setter loading instead of this.
   */
  private _loading = true;

  get loading() {
    return this._loading;
  }

  set loading(loading: boolean) {
    if (this._loading === loading) return;
    const oldLoading = this._loading;
    this._loading = loading;
    fire(this, 'loading-changed', {value: this._loading});
    this.requestUpdate('loading', oldLoading);
  }

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

  @property({type: Object})
  diff?: DiffInfo;

  @state()
  private diffTableClass = '';

  @property({type: Object})
  baseImage?: ImageInfo;

  @property({type: Object})
  revisionImage?: ImageInfo;

  /**
   * In order to allow multi-select in Safari browsers, a workaround is required
   * to trigger 'beforeinput' events to get a list of static ranges. This is
   * obtained by making the content of the diff table "contentEditable".
   */
  @property({type: Boolean})
  override isContentEditable = isSafari();

  /**
   * Whether the safety check for large diffs when whole-file is set has
   * been bypassed. If the value is null, then the safety has not been
   * bypassed. If the value is a number, then that number represents the
   * context preference to use when rendering the bypassed diff.
   *
   * Private but used in tests.
   */
  @state()
  safetyBypass: number | null = null;

  // Private but used in tests.
  @state()
  showWarning?: boolean;

  @property({type: String})
  errorMessage: string | null = null;

  @property({type: Array})
  blame: BlameInfo[] | null = null;

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

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

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

  // Private but used in tests.
  @state()
  diffLength?: number;

  /**
   * Observes comment nodes added or removed at any point.
   * Can be used to unregister upon detachment.
   */
  private nodeObserver?: MutationObserver;

  @property({type: Array})
  layers?: DiffLayer[];

  // Private but used in tests.
  renderDiffTableTask?: DelayedPromise<void>;

  // Private but used in tests.
  diffSelection = new GrDiffSelection();

  // Private but used in tests.
  highlights = new GrDiffHighlight();

  // Private but used in tests.
  diffBuilder = new GrDiffBuilderElement();

  private diffModel = new DiffModel(undefined);

  static override get styles() {
    return [
      iconStyles,
      sharedStyles,
      grSyntaxTheme,
      grRangedCommentTheme,
      css`
        /**
          This is used to hide all left side of the diff (e.g. diffs besides
          comments in the change log). Since we want to remove the first 4
          cells consistently in all rows except context buttons (.dividerRow).
        */
        :host(.no-left) .sideBySide colgroup col:nth-child(-n + 4),
        :host(.no-left) .sideBySide tr:not(.dividerRow) td:nth-child(-n + 4) {
          display: none;
        }
        :host(.disable-context-control-buttons) {
          --context-control-display: none;
        }
        :host(.disable-context-control-buttons) .section {
          border-right: none;
        }
        :host(.hide-line-length-indicator) .full-width td.content .contentText {
          background-image: none;
        }

        :host {
          font-family: var(--monospace-font-family, ''), 'Roboto Mono';
          font-size: var(--font-size, var(--font-size-code, 12px));
          /* usually 16px = 12px + 4px */
          line-height: calc(
            var(--font-size, var(--font-size-code, 12px)) +
              var(--spacing-s, 4px)
          );
        }

        .thread-group {
          display: block;
          max-width: var(--content-width, 80ch);
          white-space: normal;
          background-color: var(--diff-blank-background-color);
        }
        .diffContainer {
          max-width: var(--diff-max-width, none);
          font-family: var(--monospace-font-family);
        }
        table {
          border-collapse: collapse;
          table-layout: fixed;
        }
        td.lineNum {
          /* Enforces background whenever lines wrap */
          background-color: var(--diff-blank-background-color);
        }

        /**
          Provides the option to add side borders (left and right) to the line
          number column.
        */
        td.lineNum,
        td.blankLineNum,
        td.moveControlsLineNumCol,
        td.contextLineNum {
          box-shadow: var(--line-number-box-shadow, unset);
        }

        /**
          Context controls break up the table visually, so we set the right
          border on individual sections to leave a gap for the divider.

          Also taken into account for max-width calculations in SHRINK_ONLY mode
          (check GrDiff.updatePreferenceStyles).
        */
        .section {
          border-right: 1px solid var(--border-color);
        }
        .section.contextControl {
          /**
            Divider inside this section must not have border; we set borders on
            the padding rows below.
          */
          border-right-width: 0;
        }
        /**
          Padding rows behind context controls. The diff is styled to be cut
          into two halves by the negative space of the divider on which the
          context control buttons are anchored.
        */
        .contextBackground {
          border-right: 1px solid var(--border-color);
        }
        .contextBackground.above {
          border-bottom: 1px solid var(--border-color);
        }
        .contextBackground.below {
          border-top: 1px solid var(--border-color);
        }

        .lineNumButton {
          display: block;
          width: 100%;
          height: 100%;
          background-color: var(--diff-blank-background-color);
          box-shadow: var(--line-number-box-shadow, unset);
        }
        td.lineNum {
          vertical-align: top;
        }

        /**
          The only way to focus this (clicking) will apply our own focus
          styling, so this default styling is not needed and distracting.
        */
        .lineNumButton:focus {
          outline: none;
        }
        gr-image-viewer {
          width: 100%;
          height: 100%;
          max-width: var(--image-viewer-max-width, 95vw);
          max-height: var(--image-viewer-max-height, 90vh);
          /**
            Defined by paper-styles default-theme and used in various
            components. background-color-secondary is a compromise between
            fairly light in light theme (where we ideally would want
            background-color-primary) yet slightly offset against the app
            background in dark mode, where drop shadows e.g. around paper-card
            are almost invisible.
          */
          --primary-background-color: var(--background-color-secondary);
        }
        .image-diff .gr-diff {
          text-align: center;
        }
        .image-diff img {
          box-shadow: var(--elevation-level-1);
          max-width: 50em;
        }
        .image-diff .right.lineNumButton {
          border-left: 1px solid var(--border-color);
        }
        .image-diff label {
          font-family: var(--font-family);
          font-style: italic;
        }
        tbody.binary-diff td {
          font-family: var(--font-family);
          font-style: italic;
          text-align: center;
          padding: var(--spacing-s) 0;
        }
        .diff-row {
          outline: none;
          user-select: none;
        }
        .diff-row.target-row.target-side-left .lineNumButton.left,
        .diff-row.target-row.target-side-right .lineNumButton.right,
        .diff-row.target-row.unified .lineNumButton {
          color: var(--primary-text-color);
        }

        /**
          Preparing selected line cells with position relative so it allows a
          positioned overlay with 'position: absolute'.
        */
        .target-row td {
          position: relative;
        }

        /**
          Defines an overlay to the selected line for drawing an outline without
          blocking user interaction (e.g. text selection).
        */
        .target-row td::before {
          border-width: 0;
          border-style: solid;
          border-color: var(--focused-line-outline-color);
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          pointer-events: none;
          user-select: none;
          content: ' ';
        }

        /**
          the outline for the selected content cell should be the same in all
          cases.
        */
        .target-row.target-side-left td.left.content::before,
        .target-row.target-side-right td.right.content::before,
        .unified.target-row td.content::before {
          border-width: 1px 1px 1px 0;
        }

        /**
          the outline for the sign cell should be always be contiguous
          top/bottom.
        */
        .target-row.target-side-left td.left.sign::before,
        .target-row.target-side-right td.right.sign::before {
          border-width: 1px 0;
        }

        /**
          For side-by-side we need to select the correct line number to
          "visually close" the outline.
        */
        .side-by-side.target-row.target-side-left td.left.lineNum::before,
        .side-by-side.target-row.target-side-right td.right.lineNum::before {
          border-width: 1px 0 1px 1px;
        }

        /**
          For unified diff we always start the overlay from the left cell
        */
        .unified.target-row td.left:not(.content)::before {
          border-width: 1px 0 1px 1px;
        }

        /**
          For unified diff we should continue the top/bottom border in right
          line number column.
        */
        .unified.target-row td.right:not(.content)::before {
          border-width: 1px 0;
        }

        .content {
          background-color: var(--diff-blank-background-color);
        }

        /**
          Describes two states of semantic tokens: whenever a token has a
          definition that can be navigated to (navigable) and whenever
          the token is actually clickable to perform this navigation.
        */
        .semantic-token.navigable {
          text-decoration-style: dotted;
          text-decoration-line: underline;
        }
        .semantic-token.navigable.clickable {
          text-decoration-style: solid;
          cursor: pointer;
        }

        /*
          The file line, which has no contentText, add some margin before the
          first comment. We cannot add padding the container because we only
          want it if there is at least one comment thread, and the slotting
          makes :empty not work as expected.
        */
        .content.file slot:first-child::slotted(.comment-thread) {
          display: block;
          margin-top: var(--spacing-xs);
        }
        .contentText {
          background-color: var(--view-background-color);
        }
        .blank {
          background-color: var(--diff-blank-background-color);
        }
        .image-diff .content {
          background-color: var(--diff-blank-background-color);
        }
        .responsive {
          width: 100%;
        }
        .responsive .contentText {
          white-space: break-spaces;
          word-break: break-all;
        }
        .lineNumButton,
        .content {
          vertical-align: top;
          white-space: pre;
        }
        .contextLineNum,
        .lineNumButton {
          -webkit-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;

          color: var(--deemphasized-text-color);
          padding: 0 var(--spacing-m);
          text-align: right;
        }
        .canComment .lineNumButton {
          cursor: pointer;
        }
        .sign {
          min-width: 1ch;
          width: 1ch;
          background-color: var(--view-background-color);
        }
        .sign.blank {
          background-color: var(--diff-blank-background-color);
        }
        .content {
          /*
            Set min width since setting width on table cells still allows them
            to shrink. Do not set max width because CJK
            (Chinese-Japanese-Korean) glyphs have variable width
          */
          min-width: var(--content-width, 80ch);
          width: var(--content-width, 80ch);
        }
        .content.add .contentText .intraline,
          /* If there are no intraline info, consider everything changed */
          .content.add.no-intraline-info .contentText,
          .sign.add.no-intraline-info,
          .delta.total .content.add .contentText {
          background-color: var(--dark-add-highlight-color);
        }
        .content.add .contentText,
        .sign.add {
          background-color: var(--light-add-highlight-color);
        }
        .content.remove .contentText .intraline,
          /* If there are no intraline info, consider everything changed */
          .content.remove.no-intraline-info .contentText,
          .delta.total .content.remove .contentText,
          .sign.remove.no-intraline-info {
          background-color: var(--dark-remove-highlight-color);
        }
        .content.remove .contentText,
        .sign.remove {
          background-color: var(--light-remove-highlight-color);
        }

        .ignoredWhitespaceOnly .sign.no-intraline-info {
          background-color: var(--view-background-color);
        }

        /* dueToRebase */
        .dueToRebase .content.add .contentText .intraline,
        .delta.total.dueToRebase .content.add .contentText {
          background-color: var(--dark-rebased-add-highlight-color);
        }
        .dueToRebase .content.add .contentText {
          background-color: var(--light-rebased-add-highlight-color);
        }
        .dueToRebase .content.remove .contentText .intraline,
        .delta.total.dueToRebase .content.remove .contentText {
          background-color: var(--dark-rebased-remove-highlight-color);
        }
        .dueToRebase .content.remove .contentText {
          background-color: var(--light-rebased-remove-highlight-color);
        }

        /* dueToMove */
        .dueToMove .sign.add,
        .dueToMove .content.add .contentText,
        .dueToMove .moveControls.movedIn .sign.right,
        .dueToMove .moveControls.movedIn .moveHeader,
        .delta.total.dueToMove .content.add .contentText {
          background-color: var(--diff-moved-in-background);
        }

        .dueToMove.changed .sign.add,
        .dueToMove.changed .content.add .contentText,
        .dueToMove.changed .moveControls.movedIn .sign.right,
        .dueToMove.changed .moveControls.movedIn .moveHeader,
        .delta.total.dueToMove.changed .content.add .contentText {
          background-color: var(--diff-moved-in-changed-background);
        }

        .dueToMove .sign.remove,
        .dueToMove .content.remove .contentText,
        .dueToMove .moveControls.movedOut .moveHeader,
        .dueToMove .moveControls.movedOut .sign.left,
        .delta.total.dueToMove .content.remove .contentText {
          background-color: var(--diff-moved-out-background);
        }

        .delta.dueToMove .movedIn .moveHeader {
          --gr-range-header-color: var(--diff-moved-in-label-color);
        }
        .delta.dueToMove.changed .movedIn .moveHeader {
          --gr-range-header-color: var(--diff-moved-in-changed-label-color);
        }
        .delta.dueToMove .movedOut .moveHeader {
          --gr-range-header-color: var(--diff-moved-out-label-color);
        }

        .moveHeader a {
          color: inherit;
        }

        /* ignoredWhitespaceOnly */
        .ignoredWhitespaceOnly .content.add .contentText .intraline,
        .delta.total.ignoredWhitespaceOnly .content.add .contentText,
        .ignoredWhitespaceOnly .content.add .contentText,
        .ignoredWhitespaceOnly .content.remove .contentText .intraline,
        .delta.total.ignoredWhitespaceOnly .content.remove .contentText,
        .ignoredWhitespaceOnly .content.remove .contentText {
          background-color: var(--view-background-color);
        }

        .content .contentText gr-diff-text:empty:after,
        .content .contentText gr-legacy-text:empty:after,
        .content .contentText:empty:after {
          /* Newline, to ensure empty lines are one line-height tall. */
          content: '\\A';
        }

        /* Context controls */
        .contextControl {
          display: var(--context-control-display, table-row-group);
          background-color: transparent;
          border: none;
          --divider-height: var(--spacing-s);
          --divider-border: 1px;
        }
        /* TODO: Is this still used? */
        .contextControl gr-button gr-icon {
          /* should match line-height of gr-button */
          font-size: var(--line-height-mono, 18px);
        }
        .contextControl td:not(.lineNumButton) {
          text-align: center;
        }

        /**
          Padding rows behind context controls. Styled as a continuation of the
          line gutters and code area.
        */
        .contextBackground > .contextLineNum {
          background-color: var(--diff-blank-background-color);
        }
        .contextBackground > td:not(.contextLineNum) {
          background-color: var(--view-background-color);
        }
        .contextBackground {
          /**
            One line of background behind the context expanders which they can
            render on top of, plus some padding.
          */
          height: calc(var(--line-height-normal) + var(--spacing-s));
        }

        .dividerCell {
          vertical-align: top;
        }
        .dividerRow.show-both .dividerCell {
          height: var(--divider-height);
        }
        .dividerRow.show-above .dividerCell,
        .dividerRow.show-above .dividerCell {
          height: 0;
        }

        .br:after {
          /* Line feed */
          content: '\\A';
        }
        .tab {
          display: inline-block;
        }
        .tab-indicator:before {
          color: var(--diff-tab-indicator-color);
          /* >> character */
          content: '\\00BB';
          position: absolute;
        }
        .special-char-indicator {
          /* spacing so elements don't collide */
          padding-right: var(--spacing-m);
        }
        .special-char-indicator:before {
          color: var(--diff-tab-indicator-color);
          content: '•';
          position: absolute;
        }
        .special-char-warning {
          /* spacing so elements don't collide */
          padding-right: var(--spacing-m);
        }
        .special-char-warning:before {
          color: var(--warning-foreground);
          content: '!';
          position: absolute;
        }
        /**
          Is defined after other background-colors, such that this
          rule wins in case of same specificity.
        */
        .trailing-whitespace,
        .content .contentText .trailing-whitespace,
        .trailing-whitespace .intraline,
        .content .contentText .trailing-whitespace .intraline {
          border-radius: var(--border-radius, 4px);
          background-color: var(--diff-trailing-whitespace-indicator);
        }
        #diffHeader {
          background-color: var(--table-header-background-color);
          border-bottom: 1px solid var(--border-color);
          color: var(--link-color);
          padding: var(--spacing-m) 0 var(--spacing-m) 48px;
        }
        #diffTable {
          /* for gr-selection-action-box positioning */
          position: relative;
        }
        #diffTable:focus {
          outline: none;
        }
        #loadingError,
        #sizeWarning {
          display: block;
          margin: var(--spacing-l) auto;
          max-width: 60em;
          text-align: center;
        }
        #loadingError {
          color: var(--error-text-color);
        }
        #sizeWarning gr-button {
          margin: var(--spacing-l);
        }
        .target-row td.blame {
          background: var(--diff-selection-background-color);
        }
        td.lost div {
          background-color: var(--info-background);
        }
        td.lost div.lost-message {
          font-family: var(--font-family, 'Roboto');
          font-size: var(--font-size-normal, 14px);
          line-height: var(--line-height-normal);
          padding: var(--spacing-s) 0;
        }
        td.lost div.lost-message gr-icon {
          padding: 0 var(--spacing-s) 0 var(--spacing-m);
          color: var(--blue-700);
        }

        col.sign,
        td.sign {
          display: none;
        }

        /* Sign column should only be shown in high-contrast mode. */
        :host(.with-sign-col) col.sign {
          display: table-column;
        }
        :host(.with-sign-col) td.sign {
          display: table-cell;
        }
        col.blame {
          display: none;
        }
        td.blame {
          display: none;
          padding: 0 var(--spacing-m);
          white-space: pre;
        }
        :host(.showBlame) col.blame {
          display: table-column;
        }
        :host(.showBlame) td.blame {
          display: table-cell;
        }
        td.blame > span {
          opacity: 0.6;
        }
        td.blame > span.startOfRange {
          opacity: 1;
        }
        td.blame .blameDate {
          font-family: var(--monospace-font-family);
          color: var(--link-color);
          text-decoration: none;
        }
        .responsive td.blame {
          overflow: hidden;
          width: 200px;
        }
        /** Support the line length indicator **/
        .responsive td.content .contentText {
          /**
            Same strategy as in
            https://stackoverflow.com/questions/1179928/how-can-i-put-a-vertical-line-down-the-center-of-a-div
          */
          background-image: linear-gradient(
            var(--line-length-indicator-color),
            var(--line-length-indicator-color)
          );
          background-size: 1px 100%;
          background-position: var(--line-limit-marker) 0;
          background-repeat: no-repeat;
        }
        .newlineWarning {
          color: var(--deemphasized-text-color);
          text-align: center;
        }
        .newlineWarning.hidden {
          display: none;
        }
        .lineNum.COVERED .lineNumButton {
          color: var(
            --coverage-covered-line-num-color,
            var(--deemphasized-text-color)
          );
          background-color: var(--coverage-covered, #e0f2f1);
        }
        .lineNum.NOT_COVERED .lineNumButton {
          color: var(
            --coverage-covered-line-num-color,
            var(--deemphasized-text-color)
          );
          background-color: var(--coverage-not-covered, #ffd1a4);
        }
        .lineNum.PARTIALLY_COVERED .lineNumButton {
          color: var(
            --coverage-covered-line-num-color,
            var(--deemphasized-text-color)
          );
          background: linear-gradient(
            to right bottom,
            var(--coverage-not-covered, #ffd1a4) 0%,
            var(--coverage-not-covered, #ffd1a4) 50%,
            var(--coverage-covered, #e0f2f1) 50%,
            var(--coverage-covered, #e0f2f1) 100%
          );
        }

        // TODO: Investigate whether this CSS is still necessary.
        /** BEGIN: Select and copy for Polymer 2 */
        /**
          Below was copied and modified from the original css in
          gr-diff-selection.html
        */
        .content,
        .contextControl,
        .blame {
          -webkit-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
        }

        .selected-left:not(.selected-comment)
          .side-by-side
          .left
          + .content
          .contentText,
        .selected-right:not(.selected-comment)
          .side-by-side
          .right
          + .content
          .contentText,
        .selected-left:not(.selected-comment)
          .unified
          .left.lineNum
          ~ .content:not(.both)
          .contentText,
        .selected-right:not(.selected-comment)
          .unified
          .right.lineNum
          ~ .content
          .contentText,
        .selected-left.selected-comment .side-by-side .left + .content .message,
        .selected-right.selected-comment
          .side-by-side
          .right
          + .content
          .message
          :not(.collapsedContent),
        .selected-comment .unified .message :not(.collapsedContent),
        .selected-blame .blame {
          -webkit-user-select: text;
          -moz-user-select: text;
          -ms-user-select: text;
          user-select: text;
        }

        /** Make comments and check results selectable when selected */
        .selected-left.selected-comment
          ::slotted(.comment-thread[diff-side='left']),
        .selected-right.selected-comment
          ::slotted(.comment-thread[diff-side='right']) {
          -webkit-user-select: text;
          -moz-user-select: text;
          -ms-user-select: text;
          user-select: text;
        }
        /** END: Select and copy for Polymer 2 */

        .whitespace-change-only-message {
          background-color: var(--diff-context-control-background-color);
          border: 1px solid var(--diff-context-control-border-color);
          text-align: center;
        }

        .token-highlight {
          background-color: var(--token-highlighting-color, #fffd54);
        }

        gr-selection-action-box {
          /**
          * Needs z-index to appear above wrapped content, since it's inserted
          * into DOM before it.
          */
          z-index: 10;
        }

        gr-diff-image-new,
        gr-diff-image-old,
        gr-diff-section,
        gr-context-controls-section,
        gr-diff-row {
          display: contents;
        }
      `,
    ];
  }

  constructor() {
    super();
    provide(this, diffModelToken, () => this.diffModel);
    this.addEventListener(
      'create-range-comment',
      (e: CustomEvent<CreateRangeCommentEventDetail>) =>
        this.handleCreateRangeComment(e)
    );
    this.addEventListener('render-content', () => this.handleRenderContent());
    this.addEventListener('moved-link-clicked', (e: MovedLinkClickedEvent) => {
      this.dispatchSelectedLine(e.detail.lineNum, e.detail.side);
    });
  }

  override connectedCallback() {
    super.connectedCallback();
    if (this.loggedIn) {
      this.addSelectionListeners();
    }
    if (this.diff && this.diffTable) {
      this.diffSelection.init(this.diff, this.diffTable);
    }
    if (this.diffTable && this.diffBuilder) {
      this.highlights.init(this.diffTable, this.diffBuilder);
    }
    this.diffBuilder.init();
  }

  override disconnectedCallback() {
    this.removeSelectionListeners();
    this.renderDiffTableTask?.cancel();
    this.diffSelection.cleanup();
    this.highlights.cleanup();
    this.diffBuilder.cleanup();
    super.disconnectedCallback();
  }

  protected override willUpdate(changedProperties: PropertyValues<this>): void {
    if (
      changedProperties.has('path') ||
      changedProperties.has('lineWrapping') ||
      changedProperties.has('viewMode') ||
      changedProperties.has('useNewImageDiffUi') ||
      changedProperties.has('prefs')
    ) {
      this.prefsChanged();
    }
    if (changedProperties.has('blame')) {
      this.blameChanged();
    }
    if (changedProperties.has('renderPrefs')) {
      this.renderPrefsChanged();
    }
    if (changedProperties.has('loggedIn')) {
      if (this.loggedIn && this.isConnected) {
        this.addSelectionListeners();
      } else {
        this.removeSelectionListeners();
      }
    }
    if (changedProperties.has('coverageRanges')) {
      this.diffBuilder.updateCoverageRanges(this.coverageRanges);
    }
    if (changedProperties.has('lineOfInterest')) {
      this.lineOfInterestChanged();
    }
  }

  protected override updated(changedProperties: PropertyValues<this>): void {
    if (changedProperties.has('diff')) {
      // diffChanged relies on diffTable ahving been rendered.
      this.diffChanged();
    }
  }

  override render() {
    return html`
      ${this.renderHeader()} ${this.renderContainer()}
      ${this.renderNewlineWarning()} ${this.renderLoadingError()}
      ${this.renderSizeWarning()}
    `;
  }

  private renderHeader() {
    const diffheaderItems = this.computeDiffHeaderItems();
    if (diffheaderItems.length === 0) return nothing;
    return html`
      <div id="diffHeader">
        ${diffheaderItems.map(item => html`<div>${item}</div>`)}
      </div>
    `;
  }

  private renderContainer() {
    const cssClasses = {
      diffContainer: true,
      unified: this.viewMode === DiffViewMode.UNIFIED,
      sideBySide: this.viewMode === DiffViewMode.SIDE_BY_SIDE,
      canComment: this.loggedIn,
    };
    return html`
      <div class=${classMap(cssClasses)} @click=${this.handleTap}>
        <table
          id="diffTable"
          class=${this.diffTableClass}
          ?contenteditable=${this.isContentEditable}
        ></table>
        ${when(
          this.showNoChangeMessage(),
          () => html`
            <div class="whitespace-change-only-message">
              This file only contains whitespace changes. Modify the whitespace
              setting to see the changes.
            </div>
          `
        )}
      </div>
    `;
  }

  private renderNewlineWarning() {
    const newlineWarning = this.computeNewlineWarning();
    if (!newlineWarning) return nothing;
    return html`<div class="newlineWarning">${newlineWarning}</div>`;
  }

  private renderLoadingError() {
    if (!this.errorMessage) return nothing;
    return html`<div id="loadingError">${this.errorMessage}</div>`;
  }

  private renderSizeWarning() {
    if (!this.showWarning) return nothing;
    // TODO: Update comment about 'Whole file' as it's not in settings.
    return html`
      <div id="sizeWarning">
        <p>
          Prevented render because "Whole file" is enabled and this diff is very
          large (about ${this.diffLength} lines).
        </p>
        <gr-button @click=${this.collapseContext}>
          Render with limited context
        </gr-button>
        <gr-button @click=${this.handleFullBypass}>
          Render anyway (may be slow)
        </gr-button>
      </div>
    `;
  }

  private addSelectionListeners() {
    document.addEventListener('selectionchange', this.handleSelectionChange);
    document.addEventListener('mouseup', this.handleMouseUp);
  }

  private removeSelectionListeners() {
    document.removeEventListener('selectionchange', this.handleSelectionChange);
    document.removeEventListener('mouseup', this.handleMouseUp);
  }

  getLineNumEls(side: Side): HTMLElement[] {
    return this.diffBuilder.getLineNumEls(side);
  }

  // Private but used in tests.
  showNoChangeMessage() {
    return (
      !this.loading &&
      this.diff &&
      !this.diff.binary &&
      this.prefs &&
      this.prefs.ignore_whitespace !== 'IGNORE_NONE' &&
      this.diffLength === 0
    );
  }

  private readonly handleSelectionChange = () => {
    // Because of shadow DOM selections, we handle the selectionchange here,
    // and pass the shadow DOM selection into gr-diff-highlight, where the
    // corresponding range is determined and normalized.
    const selection = this.getShadowOrDocumentSelection();
    this.highlights.handleSelectionChange(selection, false);
  };

  private readonly handleMouseUp = () => {
    // To handle double-click outside of text creating comments, we check on
    // mouse-up if there's a selection that just covers a line change. We
    // can't do that on selection change since the user may still be dragging.
    const selection = this.getShadowOrDocumentSelection();
    this.highlights.handleSelectionChange(selection, true);
  };

  /** Gets the current selection, preferring the shadow DOM selection. */
  private getShadowOrDocumentSelection() {
    // When using native shadow DOM, the selection returned by
    // document.getSelection() cannot reference the actual DOM elements making
    // up the diff in Safari because they are in the shadow DOM of the gr-diff
    // element. This takes the shadow DOM selection if one exists.
    return this.shadowRoot?.getSelection
      ? this.shadowRoot.getSelection()
      : isSafari()
      ? getContentEditableRange()
      : document.getSelection();
  }

  private updateRanges(
    addedThreadEls: GrDiffThreadElement[],
    removedThreadEls: GrDiffThreadElement[]
  ) {
    function commentRangeFromThreadEl(
      threadEl: GrDiffThreadElement
    ): CommentRangeLayer | undefined {
      const side = getSide(threadEl);
      if (!side) return undefined;
      const range = getRange(threadEl);
      if (!range) return undefined;

      return {side, range, rootId: threadEl.rootId};
    }

    // TODO(brohlfs): Rewrite `.map().filter() as ...` with `.reduce()` instead.
    const addedCommentRanges = addedThreadEls
      .map(commentRangeFromThreadEl)
      .filter(range => !!range) as CommentRangeLayer[];
    const removedCommentRanges = removedThreadEls
      .map(commentRangeFromThreadEl)
      .filter(range => !!range) as CommentRangeLayer[];
    for (const removedCommentRange of removedCommentRanges) {
      const i = this.commentRanges.findIndex(
        cr =>
          cr.side === removedCommentRange.side &&
          rangesEqual(cr.range, removedCommentRange.range)
      );
      this.commentRanges.splice(i, 1);
    }

    if (addedCommentRanges?.length) {
      this.commentRanges.push(...addedCommentRanges);
    }
    if (this.highlightRange) {
      this.commentRanges.push({
        side: Side.RIGHT,
        range: this.highlightRange,
        rootId: '',
      });
    }

    this.diffBuilder.updateCommentRanges(this.commentRanges);
  }

  /**
   * The key locations based on the comments and line of interests,
   * where lines should not be collapsed.
   *
   */
  private computeKeyLocations() {
    const keyLocations: KeyLocations = {left: {}, right: {}};
    if (this.lineOfInterest) {
      const side = this.lineOfInterest.side;
      keyLocations[side][this.lineOfInterest.lineNum] = true;
    }
    const threadEls = [...this.childNodes].filter(isThreadEl);

    for (const threadEl of threadEls) {
      const side = getSide(threadEl);
      if (!side) continue;
      const lineNum = getLine(threadEl);
      const commentRange = getRange(threadEl);
      keyLocations[side][lineNum] = true;
      // Add start_line as well if exists,
      // the being and end of the range should not be collapsed.
      if (commentRange?.start_line) {
        keyLocations[side][commentRange.start_line] = true;
      }
    }
    return keyLocations;
  }

  // Dispatch events that are handled by the gr-diff-highlight.
  private redispatchHoverEvents(
    hoverEl: HTMLElement,
    threadEl: GrDiffThreadElement
  ) {
    hoverEl.addEventListener('mouseenter', () => {
      fire(threadEl, 'comment-thread-mouseenter', {});
    });
    hoverEl.addEventListener('mouseleave', () => {
      fire(threadEl, 'comment-thread-mouseleave', {});
    });
  }

  /** Cancel any remaining diff builder rendering work. */
  cancel() {
    this.diffBuilder.cleanup();
    this.renderDiffTableTask?.cancel();
  }

  getCursorStops(): Array<HTMLElement | AbortStop> {
    if (this.hidden && this.noAutoRender) return [];

    // Get rendered stops.
    const stops: Array<HTMLElement | AbortStop> =
      this.diffBuilder.getLineNumberRows();

    // If we are still loading this diff, abort after the rendered stops to
    // avoid skipping over to e.g. the next file.
    if (this.loading) {
      stops.push(new AbortStop());
    }
    return stops;
  }

  isRangeSelected() {
    return !!this.highlights.selectedRange;
  }

  toggleLeftDiff() {
    toggleClass(this, 'no-left');
  }

  private blameChanged() {
    this.diffBuilder.setBlame(this.blame);
    if (this.blame) {
      this.classList.add('showBlame');
    } else {
      this.classList.remove('showBlame');
    }
  }

  // Private but used in tests.
  handleTap(e: Event) {
    const el = e.target as Element;

    if (
      el.getAttribute('data-value') !== 'LOST' &&
      (el.classList.contains('lineNum') ||
        el.classList.contains('lineNumButton'))
    ) {
      this.addDraftAtLine(el);
    } else if (
      el.tagName === 'HL' ||
      el.classList.contains('content') ||
      el.classList.contains('contentText')
    ) {
      const target = getLineElByChild(el);
      if (target) {
        this.selectLine(target);
      }
    }
  }

  // Private but used in tests.
  selectLine(el: Element) {
    const lineNumber = Number(el.getAttribute('data-value'));
    const side = el.classList.contains('left') ? Side.LEFT : Side.RIGHT;
    this.dispatchSelectedLine(lineNumber, side);
  }

  private dispatchSelectedLine(number: LineNumber, side: Side) {
    fire(this, 'line-selected', {
      number,
      side,
      path: this.path,
    });
  }

  addDraftAtLine(el: Element) {
    this.selectLine(el);

    const lineNum = getLineNumber(el);
    if (lineNum === null) {
      fireAlert(this, 'Invalid line number');
      return;
    }

    this.createComment(el, lineNum);
  }

  createRangeComment() {
    if (!this.isRangeSelected()) {
      throw Error('Selection is needed for new range comment');
    }
    const selectedRange = this.highlights.selectedRange;
    if (!selectedRange) throw Error('selected range not set');
    const {side, range} = selectedRange;
    this.createCommentForSelection(side, range);
  }

  createCommentForSelection(side: Side, range: CommentRange) {
    const lineNum = range.end_line;
    const lineEl = this.diffBuilder.getLineElByNumber(lineNum, side);
    if (lineEl) {
      this.createComment(lineEl, lineNum, side, range);
    }
  }

  private handleCreateRangeComment(
    e: CustomEvent<CreateRangeCommentEventDetail>
  ) {
    const range = e.detail.range;
    const side = e.detail.side;
    this.createCommentForSelection(side, range);
  }

  // Private but used in tests.
  createComment(
    lineEl: Element,
    lineNum: LineNumber,
    side?: Side,
    range?: CommentRange
  ) {
    const contentEl = this.diffBuilder.getContentTdByLineEl(lineEl);
    if (!contentEl) throw new Error('content el not found for line el');
    side = side ?? this.getCommentSideByLineAndContent(lineEl, contentEl);
    assertIsDefined(this.path, 'path');
    fire(this, 'create-comment', {
      path: this.path,
      side,
      lineNum,
      range,
    });
  }

  private getCommentSideByLineAndContent(
    lineEl: Element,
    contentEl: Element
  ): Side {
    return lineEl.classList.contains(Side.LEFT) ||
      contentEl.classList.contains('remove')
      ? Side.LEFT
      : Side.RIGHT;
  }

  private lineOfInterestChanged() {
    if (this.loading) return;
    if (!this.lineOfInterest) return;
    const lineNum = this.lineOfInterest.lineNum;
    if (typeof lineNum !== 'number') return;
    this.diffBuilder.unhideLine(lineNum, this.lineOfInterest.side);
  }

  private cleanup() {
    this.cancel();
    this.blame = null;
    this.safetyBypass = null;
    this.showWarning = false;
    this.clearDiffContent();
  }

  private prefsChanged() {
    if (!this.prefs) return;
    this.diffModel.updateState({diffPrefs: this.prefs});

    this.blame = null;
    this.updatePreferenceStyles();

    if (this.diff && !this.noRenderOnPrefsChange) {
      this.debounceRenderDiffTable();
    }
  }

  private updatePreferenceStyles() {
    assertIsDefined(this.prefs, 'prefs');
    const lineLength =
      this.path === COMMIT_MSG_PATH
        ? COMMIT_MSG_LINE_LENGTH
        : this.prefs.line_length;
    const sideBySide = this.viewMode === 'SIDE_BY_SIDE';

    const responsiveMode = getResponsiveMode(this.prefs, this.renderPrefs);
    const responsive = isResponsive(responsiveMode);
    this.diffTableClass = responsive ? 'responsive' : '';
    const lineLimit = `${lineLength}ch`;
    this.style.setProperty(
      '--line-limit-marker',
      responsiveMode === 'FULL_RESPONSIVE' ? lineLimit : '-1px'
    );
    this.style.setProperty('--content-width', responsive ? 'none' : lineLimit);
    if (responsiveMode === 'SHRINK_ONLY') {
      // Calculating ideal (initial) width for the whole table including
      // width of each table column (content and line number columns) and
      // border. We also add a 1px correction as some values are calculated
      // in 'ch'.

      // We might have 1 to 2 columns for content depending if side-by-side
      // or unified mode
      const contentWidth = `${sideBySide ? 2 : 1} * ${lineLimit}`;

      // We always have 2 columns for line number
      const lineNumberWidth = `2 * ${getLineNumberCellWidth(this.prefs)}px`;

      // border-right in ".section" css definition (in gr-diff_html.ts)
      const sectionRightBorder = '1px';

      // each sign col has 1ch width.
      const signColsWidth =
        sideBySide && this.renderPrefs?.show_sign_col ? '2ch' : '0ch';

      // As some of these calculations are done using 'ch' we end up having <1px
      // difference between ideal and calculated size for each side leading to
      // lines using the max columns (e.g. 80) to wrap (decided exclusively by
      // the browser).This happens even in monospace fonts. Empirically adding
      // 2px as correction to be sure wrapping won't happen in these cases so it
      // doesn't block further experimentation with the SHRINK_MODE. This was
      // previously set to 1px but due to to a more aggressive text wrapping
      // (via word-break: break-all; - check .contextText) we need to be even
      // more lenient in some cases. If we find another way to avoid this
      // correction we will change it.
      const dontWrapCorrection = '2px';
      this.style.setProperty(
        '--diff-max-width',
        `calc(${contentWidth} + ${lineNumberWidth} + ${signColsWidth} + ${sectionRightBorder} + ${dontWrapCorrection})`
      );
    } else {
      this.style.setProperty('--diff-max-width', 'none');
    }
    if (this.prefs.font_size) {
      this.style.setProperty('--font-size', `${this.prefs.font_size}px`);
    }
  }

  private renderPrefsChanged() {
    this.diffModel.updateState({renderPrefs: this.renderPrefs});
    if (this.renderPrefs.hide_left_side) {
      this.classList.add('no-left');
    }
    if (this.renderPrefs.disable_context_control_buttons) {
      this.classList.add('disable-context-control-buttons');
    }
    if (this.renderPrefs.hide_line_length_indicator) {
      this.classList.add('hide-line-length-indicator');
    }
    if (this.renderPrefs.show_sign_col) {
      this.classList.add('with-sign-col');
    }
    if (this.prefs) {
      this.updatePreferenceStyles();
    }
    this.diffBuilder.updateRenderPrefs(this.renderPrefs);
  }

  private diffChanged() {
    this.loading = true;
    this.cleanup();
    if (this.diff) {
      this.diffLength = this.getDiffLength(this.diff);
      this.debounceRenderDiffTable();
      assertIsDefined(this.diffTable, 'diffTable');
      this.diffSelection.init(this.diff, this.diffTable);
      this.highlights.init(this.diffTable, this.diffBuilder);
    }
  }

  // Implemented so the test can stub it.
  getDiffLength(diff?: DiffInfo) {
    return getDiffLength(diff);
  }

  /**
   * When called multiple times from the same task, will call
   * _renderDiffTable only once, in the next task (scheduled via `setTimeout`).
   *
   * This should be used instead of calling _renderDiffTable directly to
   * render the diff in response to an input change, because there may be
   * multiple inputs changing in the same microtask, but we only want to
   * render once.
   */
  private debounceRenderDiffTable() {
    // at this point gr-diff might be considered as rendered from the outside
    // (client), although it was not actually rendered. Clients need to know
    // when it is safe to perform operations like cursor moves, for example,
    // and if changing an input actually requires a reload of the diff table.
    // Since `fire` is synchronous it allows clients to be aware when an
    // async render is needed and that they can wait for a further `render`
    // event to actually take further action.
    fire(this, 'render-required', {});
    this.renderDiffTableTask = debounceP(
      this.renderDiffTableTask,
      async () => await this.renderDiffTable()
    );
    this.renderDiffTableTask.catch((e: unknown) => {
      if (e === DELAYED_CANCELLATION) return;
      throw e;
    });
  }

  // Private but used in tests.
  async renderDiffTable() {
    this.unobserveNodes();
    if (!this.diff || !this.prefs) {
      fire(this, 'render', {});
      return;
    }
    if (
      this.prefs.context === -1 &&
      this.diffLength &&
      this.diffLength >= LARGE_DIFF_THRESHOLD_LINES &&
      this.safetyBypass === null
    ) {
      this.showWarning = true;
      fire(this, 'render', {});
      return;
    }

    this.showWarning = false;

    const keyLocations = this.computeKeyLocations();

    this.diffModel.setState({
      diff: this.diff,
      path: this.path,
      renderPrefs: this.renderPrefs,
      diffPrefs: this.prefs,
    });

    // TODO: Setting tons of public properties like this is obviously a code
    // smell. We are introducing a diff model for managing all this
    // data. Then diff builder will only need access to that model.
    this.diffBuilder.prefs = this.getBypassPrefs();
    this.diffBuilder.renderPrefs = this.renderPrefs;
    this.diffBuilder.diff = this.diff;
    this.diffBuilder.path = this.path;
    this.diffBuilder.viewMode = this.viewMode;
    this.diffBuilder.layers = this.layers ?? [];
    this.diffBuilder.isImageDiff = this.isImageDiff;
    this.diffBuilder.baseImage = this.baseImage ?? null;
    this.diffBuilder.revisionImage = this.revisionImage ?? null;
    this.diffBuilder.useNewImageDiffUi = this.useNewImageDiffUi;
    this.diffBuilder.diffElement = this.diffTable;
    // `this.commentRanges` are probably empty here, because they will only be
    // populated by the node observer, which starts observing *after* rendering.
    this.diffBuilder.updateCommentRanges(this.commentRanges);
    this.diffBuilder.updateCoverageRanges(this.coverageRanges);
    await this.diffBuilder.render(keyLocations);
  }

  private handleRenderContent() {
    this.querySelectorAll('gr-ranged-comment-hint').forEach(element =>
      element.remove()
    );
    this.loading = false;
    this.observeNodes();
    // We are just converting 'render-content' into 'render' here. Maybe we
    // should retire the 'render' event in favor of 'render-content'?
    fire(this, 'render', {});
  }

  private observeNodes() {
    // First stop observing old nodes.
    this.unobserveNodes();
    // Then introduce a Mutation observer that watches for children being added
    // to gr-diff. If those children are `isThreadEl`, namely then they are
    // processed.
    this.nodeObserver = new MutationObserver(mutations => {
      const addedThreadEls = extractAddedNodes(mutations).filter(isThreadEl);
      const removedThreadEls =
        extractRemovedNodes(mutations).filter(isThreadEl);
      this.processNodes(addedThreadEls, removedThreadEls);
    });
    this.nodeObserver.observe(this, {childList: true});
    // Make sure to process existing gr-comment-threads that already exist.
    this.processNodes([...this.childNodes].filter(isThreadEl), []);
  }

  private processNodes(
    addedThreadEls: GrDiffThreadElement[],
    removedThreadEls: GrDiffThreadElement[]
  ) {
    this.updateRanges(addedThreadEls, removedThreadEls);
    addedThreadEls.forEach(threadEl =>
      this.redispatchHoverEvents(threadEl, threadEl)
    );
    // Removed nodes do not need to be handled because all this code does is
    // adding a slot for the added thread elements, and the extra slots do
    // not hurt. It's probably a bigger performance cost to remove them than
    // to keep them around. Medium term we can even consider to add one slot
    // for each line from the start.
    for (const threadEl of addedThreadEls) {
      const lineNum = getLine(threadEl);
      const commentSide = getSide(threadEl);
      const range = getRange(threadEl);
      if (!commentSide) continue;
      const lineEl = this.diffBuilder.getLineElByNumber(lineNum, commentSide);
      // When the line the comment refers to does not exist, log an error
      // but don't crash. This can happen e.g. if the API does not fully
      // validate e.g. (robot) comments
      if (!lineEl) {
        console.error(
          'thread attached to line ',
          commentSide,
          lineNum,
          ' which does not exist.'
        );
        continue;
      }
      const contentEl = this.diffBuilder.getContentTdByLineEl(lineEl);
      if (!contentEl) continue;
      if (lineNum === 'LOST') {
        this.insertPortedCommentsWithoutRangeMessage(contentEl);
      }

      const slotAtt = threadEl.getAttribute('slot');
      if (range && isLongCommentRange(range) && slotAtt) {
        const longRangeCommentHint = document.createElement(
          'gr-ranged-comment-hint'
        );
        longRangeCommentHint.range = range;
        longRangeCommentHint.setAttribute('threadElRootId', threadEl.rootId);
        longRangeCommentHint.setAttribute('slot', slotAtt);
        this.insertBefore(longRangeCommentHint, threadEl);
        this.redispatchHoverEvents(longRangeCommentHint, threadEl);
      }
    }

    for (const threadEl of removedThreadEls) {
      this.querySelector(
        `gr-ranged-comment-hint[threadElRootId="${threadEl.rootId}"]`
      )?.remove();
    }
  }

  private unobserveNodes() {
    if (this.nodeObserver) {
      this.nodeObserver.disconnect();
      this.nodeObserver = undefined;
    }
    // You only stop observing for comment thread elements when the diff is
    // completely rendered from scratch. And then comment thread elements
    // will be (re-)added *after* rendering is done. That is also when we
    // re-start observing. So it is appropriate to thoroughly clean up
    // everything that the observer is managing.
    this.commentRanges = [];
  }

  private insertPortedCommentsWithoutRangeMessage(lostCell: Element) {
    const existingMessage = lostCell.querySelector('div.lost-message');
    if (existingMessage) return;

    const div = document.createElement('div');
    div.className = 'lost-message';
    const icon = document.createElement('gr-icon');
    icon.setAttribute('icon', 'info');
    div.appendChild(icon);
    const span = document.createElement('span');
    span.innerText = 'Original comment position not found in this patchset';
    div.appendChild(span);
    lostCell.insertBefore(div, lostCell.firstChild);
  }

  /**
   * Get the preferences object including the safety bypass context (if any).
   */
  private getBypassPrefs() {
    assertIsDefined(this.prefs, 'prefs');
    if (this.safetyBypass !== null) {
      return {...this.prefs, context: this.safetyBypass};
    }
    return this.prefs;
  }

  clearDiffContent() {
    this.unobserveNodes();
    if (!this.diffTable) return;
    while (this.diffTable.hasChildNodes()) {
      this.diffTable.removeChild(this.diffTable.lastChild!);
    }
  }

  // Private but used in tests.
  computeDiffHeaderItems() {
    return (this.diff?.diff_header ?? [])
      .filter(
        item =>
          !(
            item.startsWith('diff --git ') ||
            item.startsWith('index ') ||
            item.startsWith('+++ ') ||
            item.startsWith('--- ') ||
            item === 'Binary files differ'
          )
      )
      .map(expandFileMode);
  }

  private handleFullBypass() {
    this.safetyBypass = FULL_CONTEXT;
    this.debounceRenderDiffTable();
  }

  private collapseContext() {
    // Uses the default context amount if the preference is for the entire file.
    this.safetyBypass =
      this.prefs?.context && this.prefs.context >= 0
        ? null
        : createDefaultDiffPrefs().context;
    this.debounceRenderDiffTable();
  }

  toggleAllContext() {
    if (!this.prefs) {
      return;
    }
    if (this.getBypassPrefs().context < 0) {
      this.collapseContext();
    } else {
      this.handleFullBypass();
    }
  }

  private computeNewlineWarning(): string | undefined {
    const messages = [];
    if (this.showNewlineWarningLeft) {
      messages.push(NO_NEWLINE_LEFT);
    }
    if (this.showNewlineWarningRight) {
      messages.push(NO_NEWLINE_RIGHT);
    }
    if (!messages.length) {
      return undefined;
    }
    return messages.join(' \u2014 '); // \u2014 - '—'
  }
}

function extractAddedNodes(mutations: MutationRecord[]) {
  return mutations.flatMap(mutation => [...mutation.addedNodes]);
}

function extractRemovedNodes(mutations: MutationRecord[]) {
  return mutations.flatMap(mutation => [...mutation.removedNodes]);
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-diff': GrDiff;
  }
  interface HTMLElementEventMap {
    'comment-thread-mouseenter': CustomEvent<{}>;
    'comment-thread-mouseleave': CustomEvent<{}>;
    'loading-changed': ValueChangedEvent<boolean>;
    'render-required': CustomEvent<{}>;
  }
}
