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

    const logpointPrefix = Sources.BreakpointEditDialog.LogpointPrefix;
    const logpointSuffix = Sources.BreakpointEditDialog._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('source-frame-breakpoint-toolbar', this.contentElement);
    toolbar.appendText(`Line ${editorLineNumber + 1}:`);

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

    self.runtime.extension(UI.TextEditorFactory).instance().then(factory => {
      const editorOptions = {lineNumbers: false, lineWrapping: true, mimeType: 'javascript', autoHeight: true};
      this._editor = factory.createEditor(editorOptions);
      this._updatePlaceholder();
      this._editor.widget().element.classList.add('condition-editor');
      this._editor.configureAutocomplete(ObjectUI.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.contentElement.addEventListener('blur', event => {
        if (event.relatedTarget && !event.relatedTarget.isSelfOrDescendant(this.element)) {
          this._finishEditing(true);
        }
      }, true);
    });
  }

  /**
   * @param {string} condition
   * @return {string}
   */
  static _conditionForLogpoint(condition) {
    return `${Sources.BreakpointEditDialog.LogpointPrefix}${condition}${Sources.BreakpointEditDialog._LogpointSuffix}`;
  }

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

  _updatePlaceholder() {
    const selectedValue = this._typeSelector.selectedOption().value;
    if (selectedValue === Sources.BreakpointEditDialog.BreakpointType.Conditional) {
      this._editor.setPlaceholder(ls`Expression to check before pausing, e.g. x > 5`);
      this._typeSelector.element.title = ls`Pause only when the condition is true`;
    } else if (selectedValue === Sources.BreakpointEditDialog.BreakpointType.Logpoint) {
      this._editor.setPlaceholder(ls`Log message, e.g. 'x is', x`);
      this._typeSelector.element.title = ls`Log a message to Console, do not break`;
    }
  }

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

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

Sources.BreakpointEditDialog.LogpointPrefix = '/** DEVTOOLS_LOGPOINT */ console.log(';
Sources.BreakpointEditDialog._LogpointSuffix = ')';

Sources.BreakpointEditDialog.BreakpointType = {
  Breakpoint: 'Breakpoint',
  Conditional: 'Conditional',
  Logpoint: 'Logpoint',
};
