// Copyright (c) 2012 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.

/**
 * Javascript for omnibox.html, served from chrome://omnibox/
 * This is used to debug omnibox ranking.  The user enters some text
 * into a box, submits it, and then sees lots of debug information
 * from the autocompleter that shows what omnibox would do with that
 * input.
 *
 * The simple object defined in this javascript file listens for
 * certain events on omnibox.html, sends (when appropriate) the
 * input text to C++ code to start the omnibox autcomplete controller
 * working, and listens from callbacks from the C++ code saying that
 * results are available.  When results (possibly intermediate ones)
 * are available, the Javascript formats them and displays them.
 */

(function() {
/**
 * @typedef {{
 *   queryInputs: QueryInputs,
 *   displayInputs: DisplayInputs,
 *   responsesHistory: !Array<!Array<!mojom.OmniboxResult>>,
 * }}
 */
let OmniboxExport;

/** @type {!BrowserProxy} */
let browserProxy;
/** @type {!OmniboxInput} */
let omniboxInput;
/** @type {!omnibox_output.OmniboxOutput} */
let omniboxOutput;
/** @type {!ExportDelegate} */
let exportDelegate;

class BrowserProxy {
  /** @param {!omnibox_output.OmniboxOutput} omniboxOutput */
  constructor(omniboxOutput) {
    /** @private {!mojom.OmniboxPageCallbackRouter} */
    this.callbackRouter_ = new mojom.OmniboxPageCallbackRouter;

    // TODO (manukh) rename method to handleNewAutocompleteResponse in order
    // to keep terminology consistent. Result refers to a single autocomplete
    // match. Response refers to the data returned from the C++
    // AutocompleteController.
    this.callbackRouter_.handleNewAutocompleteResult.addListener(
        (response, isPageController) => {
          // When unfocusing the browser omnibox, the autocomplete controller
          // sends a response with no combined results. This response is ignored
          // in order to prevent the previous non-empty response from being
          // hidden and because these results wouldn't normally be displayed by
          // the browser window omnibox.
          if (isPageController ||
              (omniboxInput.connectWindowOmnibox &&
               response.combinedResults.length)) {
            omniboxOutput.addAutocompleteResponse(response);
          }
        });
    this.callbackRouter_.handleNewAutocompleteQuery.addListener(
        isPageController => {
          if (isPageController || omniboxInput.connectWindowOmnibox) {
            omniboxOutput.prepareNewQuery();
          }
        });
    this.callbackRouter_.handleAnswerImageData.addListener(
        omniboxOutput.updateAnswerImage.bind(omniboxOutput));

    /** @private {!mojom.OmniboxPageHandlerProxy} */
    this.handler_ = mojom.OmniboxPageHandler.getProxy();
    this.handler_.setClientPage(this.callbackRouter_.createProxy());

    /**
     * @type {function(string, boolean, number, boolean, boolean, boolean,
     *     string, number)}
     */
    this.makeRequest = this.handler_.startOmniboxQuery.bind(this.handler_);
  }
}

document.addEventListener('DOMContentLoaded', () => {
  omniboxInput = /** @type {!OmniboxInput} */ ($('omnibox-input'));
  omniboxOutput =
      /** @type {!omnibox_output.OmniboxOutput} */ ($('omnibox-output'));
  browserProxy = new BrowserProxy(omniboxOutput);
  exportDelegate = new ExportDelegate(omniboxOutput, omniboxInput);

  omniboxInput.addEventListener('query-inputs-changed', event => {
    omniboxOutput.updateQueryInputs(event.detail);
    browserProxy.makeRequest(
        event.detail.inputText, event.detail.resetAutocompleteController,
        event.detail.cursorPosition, event.detail.zeroSuggest,
        event.detail.preventInlineAutocomplete, event.detail.preferKeyword,
        event.detail.currentUrl, event.detail.pageClassification);
  });
  omniboxInput.addEventListener(
      'display-inputs-changed',
      event => omniboxOutput.updateDisplayInputs(event.detail));
  omniboxInput.addEventListener(
      'filter-input-changed',
      event => omniboxOutput.updateFilterText(event.detail));
  omniboxInput.addEventListener(
      'import-json', event => exportDelegate.importJson(event.detail));
  omniboxInput.addEventListener('copy-text', () => exportDelegate.copyText());
  omniboxInput.addEventListener(
      'download-json', () => exportDelegate.downloadJson());
  omniboxInput.addEventListener(
      'response-select',
      event => omniboxOutput.updateSelectedResponseIndex(event.detail));

  omniboxOutput.addEventListener(
      'responses-count-changed',
      event => omniboxInput.responsesCount = event.detail);
});

class ExportDelegate {
  /**
   * @param {!omnibox_output.OmniboxOutput} omniboxOutput
   * @param {!OmniboxInput} omniboxInput
   */
  constructor(omniboxOutput, omniboxInput) {
    /** @private {!OmniboxInput} */
    this.omniboxInput_ = omniboxInput;
    /** @private {!omnibox_output.OmniboxOutput} */
    this.omniboxOutput_ = omniboxOutput;
  }

  /** @param {OmniboxExport} importData */
  importJson(importData) {
    // This is the minimum validation required to ensure no console errors.
    // Invalid importData that passes validation will be processed with a
    // best-attempt; e.g. if responses are missing 'relevance' values, then
    // those cells will be left blank.
    const valid = importData && importData.queryInputs &&
        importData.displayInputs &&
        Array.isArray(importData.responsesHistory) &&
        importData.responsesHistory.every(
            responses => Array.isArray(responses) &&
                responses.every(
                    response => Array.isArray(response.combinedResults) &&
                        Array.isArray(response.resultsByProvider)));
    if (!valid) {
      return console.error(
          'invalid import format:',
          'expected {queryInputs: {}, displayInputs: {}, responsesHistory: []}');
    }
    this.omniboxInput_.queryInputs = importData.queryInputs;
    this.omniboxInput_.displayInputs = importData.displayInputs;
    this.omniboxOutput_.updateQueryInputs(importData.queryInputs);
    this.omniboxOutput_.updateDisplayInputs(importData.displayInputs);
    this.omniboxOutput_.setResponsesHistory(importData.responsesHistory);
  }

  copyText() {
    ExportDelegate.copy_(this.omniboxOutput_.visibleTableText);
  }

  downloadJson() {
    /** @type {OmniboxExport} */
    const exportObj = {
      queryInputs: this.omniboxInput_.queryInputs,
      displayInputs: this.omniboxInput_.displayInputs,
      responsesHistory: this.omniboxOutput_.responsesHistory,
    };
    const fileName = `omnibox_debug_export_${exportObj.queryInputs.inputText}_${
        new Date().toISOString()}.json`;
    ExportDelegate.download_(exportObj, fileName);
  }

  /** @private @param {string} value */
  static copy_(value) {
    navigator.clipboard.writeText(value).catch(
        error => console.error('unable to copy to clipboard:', error));
  }

  /**
   * @private
   * @param {Object} object
   * @param {string} fileName
   */
  static download_(object, fileName) {
    const content = JSON.stringify(object, null, 2);
    const blob = new Blob([content], {type: 'application/json'});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    a.click();
  }
}
})();
