// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

export default class ChangesView extends UI.VBox {
  constructor() {
    super(true);
    this.registerRequiredCSS('changes/changesView.css');
    const splitWidget = new UI.SplitWidget(true /* vertical */, false /* sidebar on left */);
    const mainWidget = new UI.Widget();
    splitWidget.setMainWidget(mainWidget);
    splitWidget.show(this.contentElement);

    this._emptyWidget = new UI.EmptyWidget('');
    this._emptyWidget.show(mainWidget.element);

    this._workspaceDiff = WorkspaceDiff.workspaceDiff();
    this._changesSidebar = new Changes.ChangesSidebar(this._workspaceDiff);
    this._changesSidebar.addEventListener(
        Changes.ChangesSidebar.Events.SelectedUISourceCodeChanged, this._selectedUISourceCodeChanged, this);
    splitWidget.setSidebarWidget(this._changesSidebar);

    /** @type {?Workspace.UISourceCode} */
    this._selectedUISourceCode = null;

    /** @type {!Array<!Changes.ChangesView.Row>} */
    this._diffRows = [];

    this._maxLineDigits = 1;

    this._editor = new TextEditor.CodeMirrorTextEditor({
      lineNumbers: true,
      lineWrapping: false,
      maxHighlightLength: Infinity  // This is to avoid CodeMirror bailing out of highlighting big diffs.
    });
    this._editor.setReadOnly(true);
    this._editor.show(mainWidget.element.createChild('div', 'editor-container'));
    this._editor.hideWidget();

    this._editor.element.addEventListener('click', this._click.bind(this), false);

    this._toolbar = new UI.Toolbar('changes-toolbar', mainWidget.element);
    const revertButton = new UI.ToolbarButton(Common.UIString('Revert all changes'), 'largeicon-undo');
    revertButton.addEventListener(UI.ToolbarButton.Events.Click, this._revert.bind(this));
    this._toolbar.appendToolbarItem(revertButton);
    this._diffStats = new UI.ToolbarText('');
    this._toolbar.appendToolbarItem(this._diffStats);
    this._toolbar.setEnabled(false);

    this._hideDiff(ls`No changes`);
    this._selectedUISourceCodeChanged();
  }

  _selectedUISourceCodeChanged() {
    this._revealUISourceCode(this._changesSidebar.selectedUISourceCode());
  }

  _revert() {
    const uiSourceCode = this._selectedUISourceCode;
    if (!uiSourceCode) {
      return;
    }
    this._workspaceDiff.revertToOriginal(uiSourceCode);
  }

  /**
   * @param {!Event} event
   */
  _click(event) {
    const selection = this._editor.selection();
    if (!selection.isEmpty()) {
      return;
    }
    const row = this._diffRows[selection.startLine];
    Common.Revealer.reveal(
        this._selectedUISourceCode.uiLocation(row.currentLineNumber - 1, selection.startColumn), false);
    event.consume(true);
  }

  /**
   * @param {?Workspace.UISourceCode} uiSourceCode
   */
  _revealUISourceCode(uiSourceCode) {
    if (this._selectedUISourceCode === uiSourceCode) {
      return;
    }

    if (this._selectedUISourceCode) {
      this._workspaceDiff.unsubscribeFromDiffChange(this._selectedUISourceCode, this._refreshDiff, this);
    }
    if (uiSourceCode && this.isShowing()) {
      this._workspaceDiff.subscribeToDiffChange(uiSourceCode, this._refreshDiff, this);
    }

    this._selectedUISourceCode = uiSourceCode;
    this._refreshDiff();
  }

  /**
   * @override
   */
  wasShown() {
    this._refreshDiff();
  }

  _refreshDiff() {
    if (!this.isShowing()) {
      return;
    }

    if (!this._selectedUISourceCode) {
      this._renderDiffRows(null);
      return;
    }
    const uiSourceCode = this._selectedUISourceCode;
    if (!uiSourceCode.contentType().isTextType()) {
      this._hideDiff(ls`Binary data`);
      return;
    }
    this._workspaceDiff.requestDiff(uiSourceCode).then(diff => {
      if (this._selectedUISourceCode !== uiSourceCode) {
        return;
      }
      this._renderDiffRows(diff);
    });
  }

  /**
   * @param {string} message
   */
  _hideDiff(message) {
    this._diffStats.setText('');
    this._toolbar.setEnabled(false);
    this._editor.hideWidget();
    this._emptyWidget.text = message;
    this._emptyWidget.showWidget();
  }

  /**
   * @param {?Diff.Diff.DiffArray} diff
   */
  _renderDiffRows(diff) {
    this._diffRows = [];

    if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal)) {
      this._hideDiff(ls`No changes`);
      return;
    }

    let insertions = 0;
    let deletions = 0;
    let currentLineNumber = 0;
    let baselineLineNumber = 0;
    const paddingLines = 3;
    const originalLines = [];
    const currentLines = [];

    for (let i = 0; i < diff.length; ++i) {
      const token = diff[i];
      switch (token[0]) {
        case Diff.Diff.Operation.Equal:
          this._diffRows.pushAll(createEqualRows(token[1], i === 0, i === diff.length - 1));
          originalLines.pushAll(token[1]);
          currentLines.pushAll(token[1]);
          break;
        case Diff.Diff.Operation.Insert:
          for (const line of token[1]) {
            this._diffRows.push(createRow(line, RowType.Addition));
          }
          insertions += token[1].length;
          currentLines.pushAll(token[1]);
          break;
        case Diff.Diff.Operation.Delete:
          deletions += token[1].length;
          originalLines.pushAll(token[1]);
          if (diff[i + 1] && diff[i + 1][0] === Diff.Diff.Operation.Insert) {
            i++;
            this._diffRows.pushAll(createModifyRows(token[1].join('\n'), diff[i][1].join('\n')));
            insertions += diff[i][1].length;
            currentLines.pushAll(diff[i][1]);
          } else {
            for (const line of token[1]) {
              this._diffRows.push(createRow(line, RowType.Deletion));
            }
          }
          break;
      }
    }

    this._maxLineDigits = Math.ceil(Math.log10(Math.max(currentLineNumber, baselineLineNumber)));

    let insertionText = '';
    if (insertions === 1) {
      insertionText = ls`${insertions} insertion (+),`;
    } else {
      insertionText = ls`${insertions} insertions (+),`;
    }

    let deletionText = '';
    if (deletions === 1) {
      deletionText = ls`${deletions} deletion (-)`;
    } else {
      deletionText = ls`${deletions} deletions (-)`;
    }

    this._diffStats.setText(`${insertionText} ${deletionText}`);
    this._toolbar.setEnabled(true);
    this._emptyWidget.hideWidget();

    this._editor.operation(() => {
      this._editor.showWidget();
      this._editor.setHighlightMode({
        name: 'devtools-diff',
        diffRows: this._diffRows,
        mimeType: /** @type {!Workspace.UISourceCode} */ (this._selectedUISourceCode).mimeType(),
        baselineLines: originalLines,
        currentLines: currentLines
      });
      this._editor.setText(this._diffRows.map(row => row.tokens.map(t => t.text).join('')).join('\n'));
      this._editor.setLineNumberFormatter(this._lineFormatter.bind(this));
    });

    /**
     * @param {!Array<string>} lines
     * @param {boolean} atStart
     * @param {boolean} atEnd
     * @return {!Array<!Changes.ChangesView.Row>}}
     */
    function createEqualRows(lines, atStart, atEnd) {
      const equalRows = [];
      if (!atStart) {
        for (let i = 0; i < paddingLines && i < lines.length; i++) {
          equalRows.push(createRow(lines[i], RowType.Equal));
        }
        if (lines.length > paddingLines * 2 + 1 && !atEnd) {
          equalRows.push(createRow(
              Common.UIString('( \u2026 Skipping %d matching lines \u2026 )', lines.length - paddingLines * 2),
              RowType.Spacer));
        }
      }
      if (!atEnd) {
        const start = Math.max(lines.length - paddingLines - 1, atStart ? 0 : paddingLines);
        let skip = lines.length - paddingLines - 1;
        if (!atStart) {
          skip -= paddingLines;
        }
        if (skip > 0) {
          baselineLineNumber += skip;
          currentLineNumber += skip;
        }

        for (let i = start; i < lines.length; i++) {
          equalRows.push(createRow(lines[i], RowType.Equal));
        }
      }
      return equalRows;
    }

    /**
     * @param {string} before
     * @param {string} after
     * @return {!Array<!Changes.ChangesView.Row>}}
     */
    function createModifyRows(before, after) {
      const internalDiff = Diff.Diff.charDiff(before, after, true /* cleanup diff */);
      const deletionRows = [createRow('', RowType.Deletion)];
      const insertionRows = [createRow('', RowType.Addition)];

      for (const token of internalDiff) {
        const text = token[1];
        const type = token[0];
        const className = type === Diff.Diff.Operation.Equal ? '' : 'inner-diff';
        const lines = text.split('\n');
        for (let i = 0; i < lines.length; i++) {
          if (i > 0 && type !== Diff.Diff.Operation.Insert) {
            deletionRows.push(createRow('', RowType.Deletion));
          }
          if (i > 0 && type !== Diff.Diff.Operation.Delete) {
            insertionRows.push(createRow('', RowType.Addition));
          }
          if (!lines[i]) {
            continue;
          }
          if (type !== Diff.Diff.Operation.Insert) {
            deletionRows[deletionRows.length - 1].tokens.push({text: lines[i], className});
          }
          if (type !== Diff.Diff.Operation.Delete) {
            insertionRows[insertionRows.length - 1].tokens.push({text: lines[i], className});
          }
        }
      }
      return deletionRows.concat(insertionRows);
    }

    /**
     * @param {string} text
     * @param {!Changes.ChangesView.RowType} type
     * @return {!Changes.ChangesView.Row}
     */
    function createRow(text, type) {
      if (type === RowType.Addition) {
        currentLineNumber++;
      }
      if (type === RowType.Deletion) {
        baselineLineNumber++;
      }
      if (type === RowType.Equal) {
        baselineLineNumber++;
        currentLineNumber++;
      }

      return {baselineLineNumber, currentLineNumber, tokens: text ? [{text, className: 'inner-diff'}] : [], type};
    }
  }

  /**
   * @param {number} lineNumber
   * @return {string}
   */
  _lineFormatter(lineNumber) {
    const row = this._diffRows[lineNumber - 1];
    let showBaseNumber = row.type === RowType.Deletion;
    let showCurrentNumber = row.type === RowType.Addition;
    if (row.type === RowType.Equal) {
      showBaseNumber = true;
      showCurrentNumber = true;
    }
    const base = showBaseNumber ? numberToStringWithSpacesPadding(row.baselineLineNumber, this._maxLineDigits) :
                                  spacesPadding(this._maxLineDigits);
    const current = showCurrentNumber ? numberToStringWithSpacesPadding(row.currentLineNumber, this._maxLineDigits) :
                                        spacesPadding(this._maxLineDigits);
    return base + spacesPadding(1) + current;
  }
}

/** @enum {string} */
export const RowType = {
  Deletion: 'deletion',
  Addition: 'addition',
  Equal: 'equal',
  Spacer: 'spacer'
};

/**
 * @implements {Common.Revealer}
 */
export class DiffUILocationRevealer {
  /**
   * @override
   * @param {!Object} diffUILocation
   * @param {boolean=} omitFocus
   * @return {!Promise}
   */
  async reveal(diffUILocation, omitFocus) {
    if (!(diffUILocation instanceof WorkspaceDiff.DiffUILocation)) {
      throw new Error('Internal error: not a diff ui location');
    }
    /** @type {!Changes.ChangesView} */
    const changesView = self.runtime.sharedInstance(Changes.ChangesView);
    await UI.viewManager.showView('changes.changes');
    changesView._changesSidebar.selectUISourceCode(diffUILocation.uiSourceCode, omitFocus);
  }
}

/* Legacy exported object */
self.Changes = self.Changes || {};

/* Legacy exported object */
Changes = Changes || {};

/**
 * @constructor
 */
Changes.ChangesView = ChangesView;

/** @enum {string} */
Changes.ChangesView.RowType = RowType;

/**
 * @typedef {!{
  *  baselineLineNumber: number,
  *  currentLineNumber: number,
  *  tokens: !Array<!{text: string, className: string}>,
  *  type: !Changes.ChangesView.RowType
  * }}
  */
Changes.ChangesView.Row;

/**
 * @implements {Common.Revealer}
 */
Changes.ChangesView.DiffUILocationRevealer = DiffUILocationRevealer;
