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

import * as ObjectUI from '../object_ui/object_ui.js';
import * as Root from '../root/root.js';
import * as UI from '../ui/ui.js';

export class BreakpointEditDialog extends UI.Widget.Widget {
  /**
   * @param {number} editorLineNumber
   * @param {string} oldCondition
   * @param {boolean} preferLogpoint
   * @param {function({committed: boolean, condition: string}): !Promise<void>} onFinish
   */
  constructor(editorLineNumber, oldCondition, preferLogpoint, onFinish) {
    super(true);
    this.registerRequiredCSS('sources/breakpointEditDialog.css', {enableLegacyPatching: true});
    this._onFinish = onFinish;
    this._finished = false;
    /** @type {?UI.TextEditor.TextEditor} */
    this._editor = null;
    this.element.tabIndex = -1;

    const logpointPrefix = LogpointPrefix;
    const logpointSuffix = LogpointSuffix;
    this._isLogpoint = oldCondition.startsWith(logpointPrefix) && oldCondition.endsWith(logpointSuffix);
    if (this._isLogpoint) {
      oldCondition = oldCondition.substring(logpointPrefix.length, oldCondition.length - logpointSuffix.length);
    }
    this._isLogpoint = this._isLogpoint || preferLogpoint;

    this.element.classList.add('sources-edit-breakpoint-dialog');
    const toolbar = new UI.Toolbar.Toolbar('source-frame-breakpoint-toolbar', this.contentElement);
    toolbar.appendText(`Line ${editorLineNumber + 1}:`);

    this._typeSelector = new UI.Toolbar.ToolbarComboBox(this._onTypeChanged.bind(this), ls`Breakpoint type`);
    this._typeSelector.createOption(ls`Breakpoint`, BreakpointType.Breakpoint);
    const conditionalOption = this._typeSelector.createOption(ls`Conditional breakpoint`, BreakpointType.Conditional);
    const logpointOption = this._typeSelector.createOption(ls`Logpoint`, BreakpointType.Logpoint);
    this._typeSelector.select(this._isLogpoint ? logpointOption : conditionalOption);
    toolbar.appendToolbarItem(this._typeSelector);

    const extension = Root.Runtime.Runtime.instance().extension(UI.TextEditor.TextEditorFactory);
    if (extension) {
      extension.instance().then(factory => {
        const editorOptions = {
          lineNumbers: false,
          lineWrapping: true,
          mimeType: 'javascript',
          autoHeight: true,
          bracketMatchingSetting: undefined,
          devtoolsAccessibleName: undefined,
          padBottom: undefined,
          maxHighlightLength: undefined,
          placeholder: undefined,
          lineWiseCopyCut: undefined,
          inputStyle: undefined,
        };
        this._editor = /** @type {!UI.TextEditor.TextEditorFactory} */ (factory).createEditor(editorOptions);
        this._updatePlaceholder();
        this._editor.widget().element.classList.add('condition-editor');
        this._editor.configureAutocomplete(
            ObjectUI.JavaScriptAutocomplete.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor));
        if (oldCondition) {
          this._editor.setText(oldCondition);
        }
        this._editor.widget().markAsExternallyManaged();
        this._editor.widget().show(this.contentElement);
        this._editor.setSelection(this._editor.fullRange());
        this._editor.widget().focus();
        this._editor.widget().element.addEventListener('keydown', this._onKeyDown.bind(this), true);
        this.element.addEventListener('blur', event => {
          if (event.relatedTarget && !/** @type {!Node} */ (event.relatedTarget).isSelfOrDescendant(this.element)) {
            this._finishEditing(true);
          }
        }, true);
      });
    }
  }

  /**
   * @param {string} condition
   * @return {string}
   */
  static _conditionForLogpoint(condition) {
    return `${LogpointPrefix}${condition}${LogpointSuffix}`;
  }

  _onTypeChanged() {
    const option = this._typeSelector.selectedOption();
    if (!option || !this._editor) {
      return;
    }
    const value = option.value;
    this._isLogpoint = value === BreakpointType.Logpoint;
    this._updatePlaceholder();
    if (value === BreakpointType.Breakpoint) {
      this._editor.setText('');
      this._finishEditing(true);
    }
  }

  _updatePlaceholder() {
    const option = this._typeSelector.selectedOption();
    if (!option || !this._editor) {
      return;
    }
    const selectedValue = option.value;
    if (selectedValue === BreakpointType.Conditional) {
      this._editor.setPlaceholder(ls`Expression to check before pausing, e.g. x > 5`);
      /** @type {!HTMLSpanElement} */ UI.Tooltip.Tooltip.install(
          (this._typeSelector.element), ls`Pause only when the condition is true`);
    } else if (selectedValue === BreakpointType.Logpoint) {
      this._editor.setPlaceholder(ls`Log message, e.g. 'x is', x`);
      /** @type {!HTMLSpanElement} */ UI.Tooltip.Tooltip.install(
          (this._typeSelector.element), ls`Log a message to Console, do not break`);
    }
  }

  /**
   * @param {boolean} committed
   */
  _finishEditing(committed) {
    if (this._finished) {
      return;
    }
    this._finished = true;
    if (!this._editor) {
      return;
    }
    this._editor.widget().detach();
    let condition = this._editor.text();
    if (this._isLogpoint) {
      condition = BreakpointEditDialog._conditionForLogpoint(condition);
    }
    this._onFinish({committed, condition});
  }

  /**
   * @param {!Event} event
   */
  async _onKeyDown(event) {
    if (!(event instanceof KeyboardEvent) || !this._editor) {
      return;
    }
    if (isEnterKey(event) && !event.shiftKey) {
      event.consume(true);
      const expression = this._editor.text();
      if (event.ctrlKey ||
          await ObjectUI.JavaScriptAutocomplete.JavaScriptAutocomplete.isExpressionComplete(expression)) {
        this._finishEditing(true);
      } else {
        this._editor.newlineAndIndent();
      }
    }
    if (isEscKey(event)) {
      this._finishEditing(false);
      event.stopImmediatePropagation();
    }
  }
}

export const LogpointPrefix = '/** DEVTOOLS_LOGPOINT */ console.log(';
export const LogpointSuffix = ')';

export const BreakpointType = {
  Breakpoint: 'Breakpoint',
  Conditional: 'Conditional',
  Logpoint: 'Logpoint',
};
