// Copyright 2018 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.

Sources.GutterDiffPlugin = class extends Sources.UISourceCodeFrame.Plugin {
  /**
   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
   * @param {!Workspace.UISourceCode} uiSourceCode
   */
  constructor(textEditor, uiSourceCode) {
    super();
    this._textEditor = textEditor;
    this._uiSourceCode = uiSourceCode;

    /** @type {!Array<!Sources.GutterDiffPlugin.GutterDecoration>} */
    this._decorations = [];
    this._textEditor.installGutter(Sources.GutterDiffPlugin.DiffGutterType, true);
    this._workspaceDiff = WorkspaceDiff.workspaceDiff();
    this._workspaceDiff.subscribeToDiffChange(this._uiSourceCode, this._update, this);
    this._update();
  }

  /**
   * @override
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {boolean}
   */
  static accepts(uiSourceCode) {
    return uiSourceCode.project().type() === Workspace.projectTypes.Network;
  }

  /**
   * @param {!Array<!Sources.GutterDiffPlugin.GutterDecoration>} removed
   * @param {!Array<!Sources.GutterDiffPlugin.GutterDecoration>} added
   */
  _updateDecorations(removed, added) {
    this._textEditor.operation(operation);

    function operation() {
      for (const decoration of removed) {
        decoration.remove();
      }
      for (const decoration of added) {
        decoration.install();
      }
    }
  }

  _update() {
    if (this._uiSourceCode) {
      this._workspaceDiff.requestDiff(this._uiSourceCode).then(this._innerUpdate.bind(this));
    } else {
      this._innerUpdate(null);
    }
  }

  /**
   * @param {?Diff.Diff.DiffArray} lineDiff
   */
  _innerUpdate(lineDiff) {
    if (!lineDiff) {
      this._updateDecorations(this._decorations, []);
      this._decorations = [];
      return;
    }

    /** @type {!Map<number, !Sources.GutterDiffPlugin.GutterDecoration>} */
    const oldDecorations = new Map();
    for (let i = 0; i < this._decorations.length; ++i) {
      const decoration = this._decorations[i];
      const lineNumber = decoration.lineNumber();
      if (lineNumber === -1) {
        continue;
      }
      oldDecorations.set(lineNumber, decoration);
    }

    const diff = SourceFrame.SourceCodeDiff.computeDiff(lineDiff);

    /** @type {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeDiff.EditType}>} */
    const newDecorations = new Map();
    for (let i = 0; i < diff.length; ++i) {
      const diffEntry = diff[i];
      for (let lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNumber) {
        newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry.type});
      }
    }

    const decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type);
    const addedDecorations = decorationDiff.added.map(
        entry => new Sources.GutterDiffPlugin.GutterDecoration(this._textEditor, entry.lineNumber, entry.type));

    this._decorations = decorationDiff.equal.concat(addedDecorations);
    this._updateDecorations(decorationDiff.removed, addedDecorations);
    this._decorationsSetForTest(newDecorations);
  }

  /**
   * @param {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeDiff.EditType}>} decorations
   */
  _decorationsSetForTest(decorations) {
  }

  /**
   * @override
   * @param {!UI.ContextMenu} contextMenu
   * @param {number} lineNumber
   * @return {!Promise}
   */
  async populateLineGutterContextMenu(contextMenu, lineNumber) {
    Sources.GutterDiffPlugin._appendRevealDiffContextMenu(contextMenu, this._uiSourceCode);
  }

  /**
   * @override
   * @param {!UI.ContextMenu} contextMenu
   * @param {number} lineNumber
   * @param {number} columnNumber
   * @return {!Promise}
   */
  async populateTextAreaContextMenu(contextMenu, lineNumber, columnNumber) {
    Sources.GutterDiffPlugin._appendRevealDiffContextMenu(contextMenu, this._uiSourceCode);
  }

  static _appendRevealDiffContextMenu(contextMenu, uiSourceCode) {
    if (!WorkspaceDiff.workspaceDiff().isUISourceCodeModified(uiSourceCode)) {
      return;
    }
    contextMenu.revealSection().appendItem(ls`Local Modifications...`, () => {
      Common.Revealer.reveal(new WorkspaceDiff.DiffUILocation(uiSourceCode));
    });
  }

  /**
   * @override
   */
  dispose() {
    for (const decoration of this._decorations) {
      decoration.remove();
    }
    WorkspaceDiff.workspaceDiff().unsubscribeFromDiffChange(this._uiSourceCode, this._update, this);
  }
};

Sources.GutterDiffPlugin.GutterDecoration = class {
  /**
   * @param {!TextEditor.CodeMirrorTextEditor} textEditor
   * @param {number} lineNumber
   * @param {!SourceFrame.SourceCodeDiff.EditType} type
   */
  constructor(textEditor, lineNumber, type) {
    this._textEditor = textEditor;
    this._position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
    this._className = '';
    if (type === SourceFrame.SourceCodeDiff.EditType.Insert) {
      this._className = 'diff-entry-insert';
    } else if (type === SourceFrame.SourceCodeDiff.EditType.Delete) {
      this._className = 'diff-entry-delete';
    } else if (type === SourceFrame.SourceCodeDiff.EditType.Modify) {
      this._className = 'diff-entry-modify';
    }
    this.type = type;
  }

  /**
   * @return {number}
   */
  lineNumber() {
    const location = this._position.resolve();
    if (!location) {
      return -1;
    }
    return location.lineNumber;
  }

  install() {
    const location = this._position.resolve();
    if (!location) {
      return;
    }
    const element = createElementWithClass('div', 'diff-marker');
    element.textContent = '\xA0';
    this._textEditor.setGutterDecoration(location.lineNumber, Sources.GutterDiffPlugin.DiffGutterType, element);
    this._textEditor.toggleLineClass(location.lineNumber, this._className, true);
  }

  remove() {
    const location = this._position.resolve();
    if (!location) {
      return;
    }
    this._textEditor.setGutterDecoration(location.lineNumber, Sources.GutterDiffPlugin.DiffGutterType, null);
    this._textEditor.toggleLineClass(location.lineNumber, this._className, false);
  }
};

/** @type {string} */
Sources.GutterDiffPlugin.DiffGutterType = 'CodeMirror-gutter-diff';

/**
 * @implements {UI.ContextMenu.Provider}
 * @unrestricted
 */
Sources.GutterDiffPlugin.ContextMenuProvider = class {
  /**
   * @override
   * @param {!Event} event
   * @param {!UI.ContextMenu} contextMenu
   * @param {!Object} target
   */
  appendApplicableItems(event, contextMenu, target) {
    let uiSourceCode = /** @type {!Workspace.UISourceCode} */ (target);
    const binding = Persistence.persistence.binding(uiSourceCode);
    if (binding) {
      uiSourceCode = binding.network;
    }
    Sources.GutterDiffPlugin._appendRevealDiffContextMenu(contextMenu, uiSourceCode);
  }
};
