/*
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @unrestricted
 */
Resources.DatabaseQueryView = class extends UI.VBox {
  constructor(database) {
    super();

    this.database = database;

    this.element.classList.add('storage-view', 'query', 'monospace');
    this.element.addEventListener('selectstart', this._selectStart.bind(this), false);

    this._promptContainer = this.element.createChild('div', 'database-query-prompt-container');
    this._promptContainer.appendChild(UI.Icon.create('smallicon-text-prompt', 'prompt-icon'));
    this._promptElement = this._promptContainer.createChild('div');
    this._promptElement.className = 'database-query-prompt';
    this._promptElement.addEventListener('keydown', this._promptKeyDown.bind(this));

    this._prompt = new UI.TextPrompt();
    this._prompt.initialize(this.completions.bind(this), ' ');
    this._proxyElement = this._prompt.attach(this._promptElement);

    this.element.addEventListener('click', this._messagesClicked.bind(this), true);
    this.element.tabIndex = 0;
    this.element.addEventListener('focus', this._prompt.focus.bind(this._prompt));
  }

  _messagesClicked() {
    if (!this._prompt.isCaretInsidePrompt() && !this.element.hasSelection()) {
      this._prompt.moveCaretToEndOfPrompt();
    }
  }

  /**
   * @param {string} expression
   * @param {string} prefix
   * @param {boolean=} force
   * @return {!Promise<!UI.SuggestBox.Suggestions>}
   */
  async completions(expression, prefix, force) {
    if (!prefix) {
      return [];
    }

    prefix = prefix.toLowerCase();
    const tableNames = await this.database.tableNames();
    return tableNames.map(name => name + ' ')
        .concat(Resources.DatabaseQueryView._SQL_BUILT_INS)
        .filter(proposal => proposal.toLowerCase().startsWith(prefix))
        .map(completion => ({text: completion}));
  }

  _selectStart(event) {
    if (this._selectionTimeout) {
      clearTimeout(this._selectionTimeout);
    }

    this._prompt.clearAutocomplete();

    /**
     * @this {Resources.DatabaseQueryView}
     */
    function moveBackIfOutside() {
      delete this._selectionTimeout;
      if (!this._prompt.isCaretInsidePrompt() && !this.element.hasSelection()) {
        this._prompt.moveCaretToEndOfPrompt();
      }
      this._prompt.autoCompleteSoon();
    }

    this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
  }

  _promptKeyDown(event) {
    if (isEnterKey(event)) {
      this._enterKeyPressed(event);
      return;
    }
  }

  async _enterKeyPressed(event) {
    event.consume(true);

    const query = this._prompt.textWithCurrentSuggestion();
    this._prompt.clearAutocomplete();

    if (!query.length) {
      return;
    }

    this._prompt.setEnabled(false);
    try {
      const result = await new Promise((resolve, reject) => {
        this.database.executeSql(
            query, (columnNames, values) => resolve({columnNames, values}), errorText => reject(errorText));
      });
      this._queryFinished(query, result.columnNames, result.values);
    } catch (e) {
      this._appendErrorQueryResult(query, e);
    }
    this._prompt.setEnabled(true);
    this._prompt.setText('');
    this._prompt.focus();
  }

  _queryFinished(query, columnNames, values) {
    const dataGrid = DataGrid.SortableDataGrid.create(columnNames, values);
    const trimmedQuery = query.trim();

    let view = null;
    if (dataGrid) {
      dataGrid.setStriped(true);
      dataGrid.renderInline();
      dataGrid.autoSizeColumns(5);
      view = dataGrid.asWidget();
    }
    this._appendViewQueryResult(trimmedQuery, view);

    if (trimmedQuery.match(/^create /i) || trimmedQuery.match(/^drop table /i)) {
      this.dispatchEventToListeners(Resources.DatabaseQueryView.Events.SchemaUpdated, this.database);
    }
  }

  /**
   * @param {string} query
   * @param {?UI.Widget} view
   */
  _appendViewQueryResult(query, view) {
    const resultElement = this._appendQueryResult(query);
    if (view) {
      view.show(resultElement);
    } else {
      resultElement.remove();
    }
    this._promptElement.scrollIntoView(false);
  }

  /**
   * @param {string} query
   * @param {string} errorText
   */
  _appendErrorQueryResult(query, errorText) {
    const resultElement = this._appendQueryResult(query);
    resultElement.classList.add('error');
    resultElement.appendChild(UI.Icon.create('smallicon-error', 'prompt-icon'));
    resultElement.createTextChild(errorText);

    this._promptElement.scrollIntoView(false);
  }

  /**
   * @param {string} query
   */
  _appendQueryResult(query) {
    const element = createElement('div');
    element.className = 'database-user-query';
    element.appendChild(UI.Icon.create('smallicon-user-command', 'prompt-icon'));
    this.element.insertBefore(element, this._promptContainer);

    const commandTextElement = createElement('span');
    commandTextElement.className = 'database-query-text';
    commandTextElement.textContent = query;
    element.appendChild(commandTextElement);

    const resultElement = createElement('div');
    resultElement.className = 'database-query-result';
    element.appendChild(resultElement);
    return resultElement;
  }
};

/** @enum {symbol} */
Resources.DatabaseQueryView.Events = {
  SchemaUpdated: Symbol('SchemaUpdated')
};

Resources.DatabaseQueryView._SQL_BUILT_INS = [
  'SELECT ', 'FROM ', 'WHERE ', 'LIMIT ', 'DELETE FROM ', 'CREATE ', 'DROP ', 'TABLE ', 'INDEX ', 'UPDATE ',
  'INSERT INTO ', 'VALUES ('
];
