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

cr.define('omnibox_output', function() {
  /**
   * @typedef  {{
   *   cursorPosition: number,
   *   time: number,
   *   done: boolean,
   *   host: string,
   *   isTypedHost: boolean,
   * }}
   */
  let ResultsDetails;

  /** @param {!Element} element*/
  function clearChildren(element) {
    while (element.firstChild) {
      element.firstChild.remove();
    }
  }

  class OmniboxOutput extends OmniboxElement {
    constructor() {
      super('omnibox-output-template');

      /** @private {number} */
      this.selectedResponseIndex_ = 0;
      /** @type {!Array<!Array<!mojom.OmniboxResult>>} */
      this.responsesHistory = [];
      /** @private {!Array<!OutputResultsGroup>} */
      this.resultsGroups_ = [];
      /** @private {!QueryInputs} */
      this.queryInputs_ = /** @type {!QueryInputs} */ ({});
      /** @private {!DisplayInputs} */
      this.displayInputs_ = OmniboxInput.defaultDisplayInputs;
      /** @private {string} */
      this.filterText_ = '';
    }

    /** @param {!QueryInputs} queryInputs */
    updateQueryInputs(queryInputs) {
      this.queryInputs_ = queryInputs;
    }

    /** @param {!DisplayInputs} displayInputs */
    updateDisplayInputs(displayInputs) {
      this.displayInputs_ = displayInputs;
      this.updateVisibility_();
    }

    /** @param {string} filterText */
    updateFilterText(filterText) {
      this.filterText_ = filterText;
      this.updateFilterHighlights_();
    }

    /** @param {!Array<!Array<!mojom.OmniboxResult>>} responsesHistory */
    setResponsesHistory(responsesHistory) {
      this.responsesHistory = responsesHistory;
      this.dispatchEvent(new CustomEvent(
          'responses-count-changed', {detail: responsesHistory.length}));
      this.updateSelectedResponseIndex(this.selectedResponseIndex_);
    }

    /** @param {number} selection */
    updateSelectedResponseIndex(selection) {
      if (selection >= 0 && selection < this.responsesHistory.length) {
        this.selectedResponseIndex_ = selection;
        this.clearResultsGroups_();
        this.responsesHistory[selection].forEach(
            this.createResultsGroup_.bind(this));
      }
    }

    prepareNewQuery() {
      this.responsesHistory.push([]);
      this.dispatchEvent(new CustomEvent(
          'responses-count-changed', {detail: this.responsesHistory.length}));
    }

    /** @param {!mojom.OmniboxResult} response */
    addAutocompleteResponse(response) {
      const lastIndex = this.responsesHistory.length - 1;
      this.responsesHistory[lastIndex].push(response);
      if (lastIndex === this.selectedResponseIndex_) {
        this.createResultsGroup_(response);
      }
    }

    /**
     * Clears result groups from the UI.
     * @private
     */
    clearResultsGroups_() {
      this.resultsGroups_ = [];
      clearChildren(this.$$('#contents'));
    }

    /**
     * Creates and adds a result group to the UI.
     * @private @param {!mojom.OmniboxResult} response
     */
    createResultsGroup_(response) {
      const resultsGroup =
          OutputResultsGroup.create(response, this.queryInputs_.cursorPosition);
      this.resultsGroups_.push(resultsGroup);
      this.$$('#contents').appendChild(resultsGroup);

      this.updateVisibility_();
      this.updateFilterHighlights_();
    }

    /**
     * @param {string} url
     * @param {string} data
     */
    updateAnswerImage(url, data) {
      this.autocompleteMatches.forEach(
          match => match.updateAnswerImage(url, data));
    }

    /**
     * Show or hide various output elements depending on display inputs.
     * 1) Show non-last result groups only if showIncompleteResults is true.
     * 2) Show the details section above each table if showDetails or
     * showIncompleteResults are true.
     * 3) Show individual results when showAllProviders is true.
     * 4) Show certain columns and headers only if they showDetails is true.
     * @private
     */
    updateVisibility_() {
      // Show non-last result groups only if showIncompleteResults is true.
      this.resultsGroups_.forEach(
          (resultsGroup, index) => resultsGroup.hidden =
              !this.displayInputs_.showIncompleteResults &&
              index !== this.resultsGroups_.length - 1);

      this.resultsGroups_.forEach(resultsGroup => {
        resultsGroup.updateVisibility(
            this.displayInputs_.showIncompleteResults,
            this.displayInputs_.showDetails,
            this.displayInputs_.showAllProviders);
      });
    }

    /** @private */
    updateFilterHighlights_() {
      this.autocompleteMatches.forEach(match => match.filter(this.filterText_));
    }

    /** @return {!Array<!OutputMatch>} */
    get autocompleteMatches() {
      return this.resultsGroups_.flatMap(
          resultsGroup => resultsGroup.autocompleteMatches);
    }

    /** @return {string} */
    get visibleTableText() {
      return this.resultsGroups_
          .flatMap(resultsGroup => resultsGroup.visibleText)
          .join('\n');
    }
  }

  /**
   * Helps track and render a results group. C++ Autocomplete typically returns
   * 3 result groups per query. It may return less if the next query is
   * submitted before all 3 have been returned. Each result group contains
   * top level information (e.g., how long the result took to generate), as well
   * as a single list of combined results and multiple lists of individual
   * results. Each of these lists is tracked and rendered by OutputResultsTable
   * below.
   */
  class OutputResultsGroup extends OmniboxElement {
    /**
     * @param {!mojom.OmniboxResult} resultsGroup
     * @param {number} cursorPosition
     * @return {!OutputResultsGroup}
     */
    static create(resultsGroup, cursorPosition) {
      const outputResultsGroup = new OutputResultsGroup();
      outputResultsGroup.setResultsGroup(resultsGroup, cursorPosition);
      return outputResultsGroup;
    }

    constructor() {
      super('output-results-group-template');
    }

    /**
     *  @param {!mojom.OmniboxResult} resultsGroup
     *  @param {number} cursorPosition
     */
    setResultsGroup(resultsGroup, cursorPosition) {
      /** @private {ResultsDetails} */
      this.details_ = {
        cursorPosition: cursorPosition,
        time: resultsGroup.timeSinceOmniboxStartedMs,
        done: resultsGroup.done,
        host: resultsGroup.host,
        isTypedHost: resultsGroup.isTypedHost
      };
      /** @type {!Array<!OutputHeader>} */
      this.headers = COLUMNS.map(OutputHeader.create);
      /** @type {!OutputResultsTable} */
      this.combinedResults =
          OutputResultsTable.create(resultsGroup.combinedResults);
      /** @type {!Array<!OutputResultsTable>} */
      this.individualResultsList =
          resultsGroup.resultsByProvider
              .map(resultsWrapper => resultsWrapper.results)
              .filter(results => results.length > 0)
              .map(OutputResultsTable.create);
      if (this.hasAdditionalProperties) {
        this.headers.push(OutputHeader.create(ADDITIONAL_PROPERTIES_COLUMN));
      }
      this.render_();
    }

    /**
     * Creates a HTML Node representing this data.
     * @private
     */
    render_() {
      clearChildren(this);

      /** @private {!Array<!Element>} */
      this.innerHeaders_ = [];

      customElements.whenDefined(this.$$('output-results-details').localName)
          .then(
              () =>
                  this.$$('output-results-details').setDetails(this.details_));

      this.$$('#table').appendChild(this.renderHeader_());
      this.$$('#table').appendChild(this.combinedResults);
      this.individualResultsList.forEach(results => {
        const innerHeader = this.renderInnerHeader_(results);
        this.innerHeaders_.push(innerHeader);
        this.$$('#table').appendChild(innerHeader);
        this.$$('#table').appendChild(results);
      });
    }

    /** @private @return {!Element} */
    renderHeader_() {
      const head = document.createElement('thead');
      head.classList.add('head');
      const row = document.createElement('tr');
      this.headers.forEach(cell => row.appendChild(cell));
      head.appendChild(row);
      return head;
    }

    /**
     * @private
     * @param {!OutputResultsTable} results
     * @return {!Element}
     */
    renderInnerHeader_(results) {
      const head = document.createElement('tbody');
      head.classList.add('head');
      const row = document.createElement('tr');
      const cell = document.createElement('th');
      // Reserve 1 more column for showing the additional properties column.
      cell.colSpan = COLUMNS.length + 1;
      cell.textContent = results.innerHeaderText;
      row.appendChild(cell);
      head.appendChild(row);
      return head;
    }

    /**
     * @param {boolean} showIncompleteResults
     * @param {boolean} showDetails
     * @param {boolean} showAllProviders
     */
    updateVisibility(showIncompleteResults, showDetails, showAllProviders) {
      // Show the details section above each table if showDetails or
      // showIncompleteResults are true.
      this.$$('output-results-details').hidden =
          !showDetails && !showIncompleteResults;

      // Show individual results when showAllProviders is true.
      this.individualResultsList.forEach(
          individualResults => individualResults.hidden = !showAllProviders);
      this.innerHeaders_.forEach(
          innerHeader => innerHeader.hidden = !showAllProviders);

      // Show certain column headers only if they showDetails is true.
      COLUMNS.forEach(
          (column, index) => this.headers[index].hidden =
              !showDetails && !column.displayAlways);

      // Show certain columns only if they showDetails is true.
      this.autocompleteMatches.forEach(
          match => match.updateVisibility(showDetails));
    }

    /**
     * @private
     * @return {boolean}
     */
    get hasAdditionalProperties() {
      return this.combinedResults.hasAdditionalProperties ||
          this.individualResultsList.some(
              results => results.hasAdditionalProperties);
    }

    /** @return {!Array<!OutputMatch>} */
    get autocompleteMatches() {
      return [this.combinedResults]
          .concat(this.individualResultsList)
          .flatMap(results => results.autocompleteMatches);
    }

    /** @return {!Array<string>} */
    get visibleText() {
      return Array.from(this.shadowRoot.querySelectorAll(':host > :not(style)'))
          .map(child => child.innerText);
    }
  }

  class OutputResultsDetails extends OmniboxElement {
    constructor() {
      super('output-results-details-template');
    }

    /** @param {ResultsDetails} details */
    setDetails(details) {
      this.$$('#cursor-position').textContent = details.cursorPosition;
      this.$$('#time').textContent = details.time;
      this.$$('#done').textContent = details.done;
      this.$$('#host').textContent = details.host;
      this.$$('#is-typed-host').textContent = details.isTypedHost;
    }
  }

  /**
   * Helps track and render a list of results. Each result is tracked and
   * rendered by OutputMatch below.
   */
  class OutputResultsTable extends HTMLTableSectionElement {
    /**
     * @param {!Array<!mojom.AutocompleteMatch>} results
     * @return {!OutputResultsTable}
     */
    static create(results) {
      const resultsTable = new OutputResultsTable();
      resultsTable.results = results;
      return resultsTable;
    }

    constructor() {
      super();
      this.classList.add('body');
      /** @type {!Array<!OutputMatch>} */
      this.autocompleteMatches = [];
    }

    /** @param {!Array<!mojom.AutocompleteMatch>} results */
    set results(results) {
      this.autocompleteMatches.forEach(match => match.remove());
      this.autocompleteMatches = results.map(OutputMatch.create);
      this.autocompleteMatches.forEach(this.appendChild.bind(this));
    }

    /** @return {?string} */
    get innerHeaderText() {
      return this.autocompleteMatches[0].providerName;
    }

    /** @return {boolean} */
    get hasAdditionalProperties() {
      return this.autocompleteMatches.some(
          match => match.hasAdditionalProperties);
    }
  }

  /** Helps track and render a single match. */
  class OutputMatch extends HTMLTableRowElement {
    /**
     * @param {!mojom.AutocompleteMatch} match
     * @return {!OutputMatch}
     */
    static create(match) {
      /** @suppress {checkTypes} */
      const outputMatch = new OutputMatch();
      outputMatch.match = match;
      return outputMatch;
    }

    /** @param {!mojom.AutocompleteMatch} match */
    set match(match) {
      /** @type {!Object<string, !OutputProperty>} */
      this.properties = {};
      /** @type {!OutputProperty} */
      this.properties.contentsAndDescription;
      /** @type {?string} */
      this.providerName = match.providerName || null;

      COLUMNS.forEach(column => {
        const values = column.sourceProperties.map(
            propertyName =>
                /** @type {Object} */ (match)[propertyName]);
        this.properties[column.matchKey] =
            OutputProperty.create(column, values);
      });

      const unconsumedProperties = {};
      Object.entries(match)
          .filter(propertyNameValueTuple => {
            const propertyName = propertyNameValueTuple[0];
            return !CONSUMED_SOURCE_PROPERTIES.includes(propertyName);
          })
          .forEach(propertyNameValueTuple => {
            const propertyName = propertyNameValueTuple[0];
            const propertyValue = propertyNameValueTuple[1];
            unconsumedProperties[propertyName] = propertyValue;
          });

      /** @type {!OutputProperty} */
      this.additionalProperties = OutputProperty.create(
          ADDITIONAL_PROPERTIES_COLUMN, [unconsumedProperties]);

      this.render_();
    }

    /** @private */
    render_() {
      clearChildren(this);
      COLUMNS.map(column => this.properties[column.matchKey])
          .forEach(cell => this.appendChild(cell));
      if (this.hasAdditionalProperties) {
        this.appendChild(this.additionalProperties);
      }
    }

    /**
     * @param {string} url
     * @param {string} data
     */
    updateAnswerImage(url, data) {
      if (this.properties.contentsAndDescription.value === url) {
        this.properties.contentsAndDescription.setAnswerImageData(data);
      }
    }

    /** @param {boolean} showDetails */
    updateVisibility(showDetails) {
      // Show certain columns only if they showDetails is true.
      COLUMNS.forEach(column => {
        this.properties[column.matchKey].hidden =
            !showDetails && !column.displayAlways;
      });
    }

    /** @param {string} filterText */
    filter(filterText) {
      this.classList.remove('filtered-highlighted');
      this.allProperties_.forEach(
          property => property.classList.remove('filtered-highlighted-nested'));

      if (!filterText) {
        return;
      }

      const matchedProperties = this.allProperties_.filter(
          property => FilterUtil.filterText(property.text, filterText));
      const isMatch = matchedProperties.length > 0;
      this.classList.toggle('filtered-highlighted', isMatch);
      matchedProperties.forEach(
          property => property.classList.add('filtered-highlighted-nested'));
    }

    /**
     * @return {boolean} Used to determine if the additional properties column
     * needs to be displayed for this match.
     */
    get hasAdditionalProperties() {
      return Object
                 .keys(/** @type {!Object} */ (this.additionalProperties.value))
                 .length > 0;
    }

    /** @private @return {!Array<!OutputProperty>} */
    get allProperties_() {
      return Object.values(this.properties).concat(this.additionalProperties);
    }
  }

  class OutputHeader extends HTMLTableCellElement {
    /**
     * @param {Column} column
     * @return {!OutputHeader}
     */
    static create(column) {
      const header = new OutputHeader();
      header.classList.add(column.headerClassName);
      header.setContents(column.headerText, column.url);
      header.title = column.tooltip;
      return header;
    }

    /**
     * @param {!Array<string>} texts
     * @param {string=} url
     */
    setContents(texts, url) {
      clearChildren(this);
      let container;
      if (url) {
        container = document.createElement('a');
        container.href = url;
      } else {
        container = document.createElement('div');
      }
      container.classList.add('header-container');
      texts.forEach(text => {
        const part = document.createElement('span');
        part.textContent = text;
        container.appendChild(part);
      });
      this.appendChild(container);
    }
  }

  class OutputProperty extends HTMLTableCellElement {
    /**
     * @param {Column} column
     * @param {!Array<*>} values
     * @return {!OutputProperty}
     */
    static create(column, values) {
      const outputProperty = new column.outputClass();
      outputProperty.classList.add(column.cellClassName);
      outputProperty.name = column.headerText.join('.');
      outputProperty.values = values;
      return outputProperty;
    }

    /** @param {!Array<*>} values */
    set values(values) {
      /** @type {*} */
      this.value = values[0];
      /** @private {!Array<*>} */
      this.values_ = values;
      /** @override */
      this.render_();
    }

    /** @private */
    render_() {}

    /** @return {string} */
    get text() {
      return this.value + '';
    }
  }

  class OutputPairProperty extends OutputProperty {
    constructor() {
      super();

      this.container_ = document.createElement('div');
      this.container_.classList.add('pair-container');
      this.appendChild(this.container_);

      /** @type {!Element} */
      this.first_ = document.createElement('div');
      this.first_.classList.add('pair-item');
      this.container_.appendChild(this.first_);

      /** @type {!Element} */
      this.second_ = document.createElement('div');
      this.second_.classList.add('pair-item');
      this.container_.appendChild(this.second_);
    }

    /** @private @override */
    render_() {
      this.first_.textContent = this.values_[0];
      this.second_.textContent = this.values_[1];
    }

    /** @override @return {string} */
    get text() {
      return `${this.values_[0]}.${this.values_[1]}`;
    }
  }

  class OutputOverlappingPairProperty extends OutputPairProperty {
    constructor() {
      super();

      this.notOverlapWarning_ = document.createElement('div');
      this.notOverlapWarning_.classList.add('overlap-warning');
      this.container_.appendChild(this.notOverlapWarning_);
    }

    /** @private @override */
    render_() {
      const overlap = this.values_[0].endsWith(this.values_[1]);
      const firstText = this.values_[1] && overlap ?
          this.values_[0].slice(0, -this.values_[1].length) :
          this.values_[0];

      this.first_.textContent = firstText;
      this.second_.textContent = this.values_[1];
      this.notOverlapWarning_.textContent = overlap ?
          '' :
          `btw, these texts do not overlap; '${
              this.values_[1]}' was expected to be a suffix of '${
              this.values_[0]}'`;
    }
  }

  class OutputAnswerProperty extends OutputProperty {
    constructor() {
      super();

      /** @private {!Element} */
      this.container_ = document.createElement('div');
      this.container_.classList.add('pair-container');
      this.appendChild(this.container_);

      /** @type {!Element} */
      this.image_ = document.createElement('img');
      this.image_.classList.add('pair-item', 'image');
      this.container_.appendChild(this.image_);

      /** @type {!Element} */
      this.contents_ = document.createElement('div');
      this.contents_.classList.add('pair-item', 'contents');
      this.container_.appendChild(this.contents_);

      /** @type {!Element} */
      this.description_ = document.createElement('div');
      this.description_.classList.add('pair-item', 'description');
      this.container_.appendChild(this.description_);

      /** @type {!Element} */
      this.answer_ = document.createElement('div');
      this.answer_.classList.add('pair-item', 'answer');
      this.container_.appendChild(this.answer_);
    }

    /** @param {string} imageData */
    setAnswerImageData(imageData) {
      this.image_.src = imageData;
    }

    /** @private @override */
    render_() {
      this.contents_.textContent = this.values_[1];
      this.description_.textContent = this.values_[2];
      this.answer_.textContent = this.values_[3];
    }

    /** @override @return {string} */
    get text() {
      return this.values_.join('.');
    }
  }

  class OutputBooleanProperty extends OutputProperty {
    constructor() {
      super();
      /** @private {!Element} */
      this.icon_ = document.createElement('div');
      this.appendChild(this.icon_);
    }

    /** @private @override */
    render_() {
      this.icon_.classList.toggle('check-mark', !!this.value);
      this.icon_.classList.toggle('x-mark', !this.value);
      this.icon_.textContent = this.value;
    }

    get text() {
      return (this.value ? 'is: ' : 'not: ') + this.name;
    }
  }

  class OutputJsonProperty extends OutputProperty {
    constructor() {
      super();
      /** @private {!Element} */
      this.pre_ = document.createElement('pre');
      this.pre_.classList.add('json');
      this.appendChild(this.pre_);
    }

    /** @private @override */
    render_() {
      clearChildren(this.pre_);
      this.text.split(/("(?:[^"\\]|\\.)*":?|\w+)/)
          .map(
              word => OutputJsonProperty.renderJsonWord(
                  word, OutputJsonProperty.classifyJsonWord(word)))
          .forEach(jsonSpan => this.pre_.appendChild(jsonSpan));
    }

    /** @override @return {string} */
    get text() {
      return JSON.stringify(this.value, null, 2);
    }

    /**
     * @param {string} word
     * @param {string|undefined} cls
     * @return {!Element}
     */
    static renderJsonWord(word, cls) {
      const span = document.createElement('span');
      if (cls) {
        span.classList.add(cls);
      }
      span.textContent = word;
      return span;
    }

    /**
     * @param {string} word
     * @return {string|undefined}
     */
    static classifyJsonWord(word) {
      if (/^\d+$/.test(word)) {
        return 'number';
      }
      if (/^"[^]*":$/.test(word)) {
        return 'key';
      }
      if (/^"[^]*"$/.test(word)) {
        return 'string';
      }
      if (/true|false/.test(word)) {
        return 'boolean';
      }
      if (/null/.test(word)) {
        return 'null';
      }
    }
  }

  class OutputKeyValueTuplesProperty extends OutputJsonProperty {
    /** @private @override */
    render_() {
      clearChildren(this.pre_);
      this.value.forEach(({key, value}) => {
        this.pre_.appendChild(
            OutputJsonProperty.renderJsonWord(key + ': ', 'key'));
        this.pre_.appendChild(
            OutputJsonProperty.renderJsonWord(value + '\n', 'number'));
      });
    }

    /** @override @return {string} */
    get text() {
      return this.value.reduce(
          (prev, {key, value}) => `${prev}${key}: ${value}\n`, '');
    }
  }

  class OutputUrlProperty extends OutputProperty {
    constructor() {
      super();

      /** @private {!Element} */
      this.container_ = document.createElement('div');
      this.container_.classList.add('pair-container');
      this.appendChild(this.container_);

      /** @private {!Element} */
      this.icon_ = document.createElement('img');
      this.container_.appendChild(this.icon_);

      /** @private {!Element} */
      this.link_ = document.createElement('a');
      this.container_.appendChild(this.link_);
    }

    /** @private @override */
    render_() {
      if (this.values_[1]) {
        this.icon_.removeAttribute('src');
      } else {
        this.icon_.src = `chrome://favicon/${this.value}`;
      }
      this.link_.textContent = this.value;
      this.link_.href = this.value;
    }
  }

  class OutputTextProperty extends OutputProperty {
    constructor() {
      super();
      /** @private {!Element} */
      this.div_ = document.createElement('div');
      this.appendChild(this.div_);
    }

    /** @private @override */
    render_() {
      this.div_.textContent = this.value;
    }
  }

  /** Responsible for highlighting and hiding rows using filter text. */
  class FilterUtil {
    /**
     * Checks if a string fuzzy-matches a filter string. Each character
     * of filterText must be present in the search text, either adjacent to the
     * previous matched character, or at the start of a new word (see
     * textToWords_).
     * E.g. `abc` matches `abc`, `a big cat`, `a-bigCat`, `a very big cat`, and
     * `an amBer cat`; but does not match `abigcat` or `an amber cat`.
     * `green rainbow` is matched by `gre rain`, but not by `gre bow`.
     * One exception is the first character, which may be matched mid-word.
     * E.g. `een rain` can also match `green rainbow`.
     * @param {string} searchText
     * @param {string} filterText
     * @return {boolean}
     */
    static filterText(searchText, filterText) {
      const regexFilter =
          Array.from(filterText)
              .map(word => word.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
              .join('(.*\\.)?');
      const words = FilterUtil.textToWords_(searchText).join('.');
      return words.match(new RegExp(regexFilter, 'i')) !== null;
    }

    /**
     * Splits a string into words, delimited by either capital letters, groups
     * of digits, or non alpha characters.
     * E.g., `https://google.com/the-dog-ate-134pies` will be split to:
     * https, :, /, /, google, ., com, /, the, -,  dog, -, ate, -, 134, pies
     * We don't use `Array.split`, because we want to group digits, e.g. 134.
     * @private
     * @param {string} text
     * @return {!Array<string>}
     */
    static textToWords_(text) {
      const MAX_TEXT_LENGTH = 200;
      if (text.length > MAX_TEXT_LENGTH) {
        text = text.slice(0, MAX_TEXT_LENGTH);
        console.warn(`text to be filtered too long, truncatd; max length: ${
            MAX_TEXT_LENGTH}, truncated text: ${text}`);
      }
      return text.match(/[a-z]+|[A-Z][a-z]*|\d+|./g) || [];
    }
  }

  class Column {
    /**
     * @param {!Array<string>} headerText
     * @param {string} url
     * @param {string} matchKey
     * @param {boolean} displayAlways
     * @param {string} tooltip
     * @param {function(new:OutputProperty)} outputClass
     * @param {!Array<string>} sourceProperties
     */
    constructor(
        headerText, url, matchKey, displayAlways, tooltip, sourceProperties,
        outputClass) {
      /** @type {!Array<string>} split per span container to support styling. */
      this.headerText = headerText;
      /** @type {string} header link href or blank if non-hyperlink header. */
      this.url = url;
      /** @type {string} the field name used in the Match.properties object. */
      this.matchKey = matchKey;
      /** @type {boolean} if shown when showDetails option is false. */
      this.displayAlways = displayAlways;
      /** @type {string} header tooltip. */
      this.tooltip = tooltip;
      /** @type {!Array<string>} related mojo AutocompleteMatch properties. */
      this.sourceProperties = sourceProperties;
      /** @type {function(new:OutputProperty)} */
      this.outputClass = outputClass;

      const hyphenatedName =
          matchKey.replace(/[A-Z]/g, c => '-' + c.toLowerCase());
      /** @type {string} */
      this.cellClassName = 'cell-' + hyphenatedName;
      /** @type {string} */
      this.headerClassName = 'header-' + hyphenatedName;
    }
  }

  /**
   * A constant that's used to decide what autocomplete result
   * properties to output in what order.
   * @type {!Array<!Column>}
   */
  const COLUMNS = [
    new Column(
        ['Provider', 'Type'], '', 'providerAndType', true,
        'The AutocompleteProvider suggesting this result. / The type of the ' +
            'result.',
        ['providerName', 'type'], OutputPairProperty),
    new Column(
        ['Relevance'], '', 'relevance', true,
        'The result score. Higher is more relevant.', ['relevance'],
        OutputTextProperty),
    new Column(
        ['Contents', 'Description', 'Answer'], '', 'contentsAndDescription',
        true,
        'The text that is presented identifying the result. / The page title ' +
            'of the result.',
        ['image', 'contents', 'description', 'answer'], OutputAnswerProperty),
    new Column(
        ['D'], '', 'allowedToBeDefaultMatch', true,
        'Can Be Default\nA green checkmark indicates that the result can be ' +
            'the default match (i.e., can be the match that pressing enter ' +
            'in the omnibox navigates to).',
        ['allowedToBeDefaultMatch'], OutputBooleanProperty),
    new Column(
        ['S'], '', 'starred', false,
        'Starred\nA green checkmark indicates that the result has been ' +
            'bookmarked.',
        ['starred'], OutputBooleanProperty),
    new Column(
        ['T'], '', 'hasTabMatch', false,
        'Has Tab Match\nA green checkmark indicates that the result URL ' +
            'matches an open tab.',
        ['hasTabMatch'], OutputBooleanProperty),
    new Column(
        ['URL'], '', 'destinationUrl', true, 'The URL for the result.',
        ['destinationUrl', 'isSearchType'], OutputUrlProperty),
    new Column(
        ['Fill', 'Inline'], '', 'fillAndInline', false,
        'The text shown in the omnibox when the result is selected. / The ' +
            'text shown in the omnibox as a blue highlight selection ' +
            'following the cursor, if this match is shown inline.',
        ['fillIntoEdit', 'inlineAutocompletion'],
        OutputOverlappingPairProperty),
    new Column(
        ['D'], '', 'deletable', false,
        'Deletable\nA green checkmark indicates that the result can be ' +
            'deleted from the visit history.',
        ['deletable'], OutputBooleanProperty),
    new Column(
        ['P'], '', 'fromPrevious', false,
        'From Previous\nTrue if this match is from a previous result.',
        ['fromPrevious'], OutputBooleanProperty),
    new Column(
        ['Tran'],
        'https://cs.chromium.org/chromium/src/ui/base/page_transition_types.h' +
            '?q=page_transition_types.h&sq=package:chromium&dr=CSs&l=14',
        'transition', false, 'How the user got to the result.', ['transition'],
        OutputTextProperty),
    new Column(
        ['D'], '', 'providerDone', false,
        'Done\nA green checkmark indicates that the provider is done looking ' +
            'for more results.',
        ['providerDone'], OutputBooleanProperty),
    new Column(
        ['Associated Keyword'], '', 'associatedKeyword', false,
        'If non-empty, a "press tab to search" hint will be shown and will ' +
            'engage this keyword.',
        ['associatedKeyword'], OutputTextProperty),
    new Column(
        ['Keyword'], '', 'keyword', false,
        'The keyword of the search engine to be used.', ['keyword'],
        OutputTextProperty),
    new Column(
        ['D'], '', 'duplicates', false,
        'Duplicates\nThe number of matches that have been marked as ' +
            'duplicates of this match.',
        ['duplicates'], OutputTextProperty),
    new Column(
        ['Additional Info'], '', 'additionalInfo', false,
        'Provider-specific information about the result.', ['additionalInfo'],
        OutputKeyValueTuplesProperty)
  ];

  /** @type {!Column} */
  const ADDITIONAL_PROPERTIES_COLUMN = new Column(
      ['Additional Properties'], '', 'additionalProperties', false,
      'Properties not accounted for.', [], OutputJsonProperty);

  const CONSUMED_SOURCE_PROPERTIES =
      COLUMNS.flatMap(column => column.sourceProperties);

  customElements.define('omnibox-output', OmniboxOutput);
  customElements.define('output-results-group', OutputResultsGroup);
  customElements.define('output-results-details', OutputResultsDetails);
  customElements.define(
      'output-results-table', OutputResultsTable, {extends: 'tbody'});
  customElements.define('output-match', OutputMatch, {extends: 'tr'});
  customElements.define('output-header', OutputHeader, {extends: 'th'});
  customElements.define(
      'output-pair-property', OutputPairProperty, {extends: 'td'});
  customElements.define(
      'output-overlapping-pair-property', OutputOverlappingPairProperty,
      {extends: 'td'});
  customElements.define(
      'output-answer-property', OutputAnswerProperty, {extends: 'td'});
  customElements.define(
      'output-boolean-property', OutputBooleanProperty, {extends: 'td'});
  customElements.define(
      'output-json-property', OutputJsonProperty, {extends: 'td'});
  customElements.define(
      'output-key-value-tuple-property', OutputKeyValueTuplesProperty,
      {extends: 'td'});
  customElements.define(
      'output-url-property', OutputUrlProperty, {extends: 'td'});
  customElements.define(
      'output-text-property', OutputTextProperty, {extends: 'td'});

  return {OmniboxOutput: OmniboxOutput};
});
