/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 * Copyright (C) IBM Corp. 2009  All rights reserved.
 * Copyright (C) 2010 Google 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.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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.
 */

export class RequestHeadersView extends UI.VBox {
  /**
   * @param {!SDK.NetworkRequest} request
   */
  constructor(request) {
    super();
    this.registerRequiredCSS('network/requestHeadersView.css');
    this.element.classList.add('request-headers-view');

    this._request = request;
    this._decodeRequestParameters = true;
    this._showRequestHeadersText = false;
    this._showResponseHeadersText = false;

    /** @type {?UI.TreeElement} */
    this._highlightedElement = null;

    const root = new UI.TreeOutlineInShadow();
    root.registerRequiredCSS('object_ui/objectValue.css');
    root.registerRequiredCSS('object_ui/objectPropertiesSection.css');
    root.registerRequiredCSS('network/requestHeadersTree.css');
    root.element.classList.add('request-headers-tree');
    root.makeDense();
    this.element.appendChild(root.element);

    const generalCategory = new Category(root, 'general', Common.UIString('General'));
    generalCategory.hidden = false;
    this._root = generalCategory;
    this._urlItem = generalCategory.createLeaf();
    this._requestMethodItem = generalCategory.createLeaf();
    this._statusCodeItem = generalCategory.createLeaf();
    this._remoteAddressItem = generalCategory.createLeaf();
    this._remoteAddressItem.hidden = true;
    this._referrerPolicyItem = generalCategory.createLeaf();
    this._referrerPolicyItem.hidden = true;

    this._responseHeadersCategory = new Category(root, 'responseHeaders', '');
    this._requestHeadersCategory = new Category(root, 'requestHeaders', '');
    this._queryStringCategory = new Category(root, 'queryString', '');
    this._formDataCategory = new Category(root, 'formData', '');
    this._requestPayloadCategory = new Category(root, 'requestPayload', Common.UIString('Request Payload'));
  }

  /**
   * @override
   */
  wasShown() {
    this._clearHighlight();
    this._request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
    this._request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
    this._request.addEventListener(
        SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
    this._request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);

    this._refreshURL();
    this._refreshQueryString();
    this._refreshRequestHeaders();
    this._refreshResponseHeaders();
    this._refreshHTTPInformation();
    this._refreshRemoteAddress();
    this._refreshReferrerPolicy();
    this._root.select(/* omitFocus */ true, /* selectedByUser */ false);
  }

  /**
   * @override
   */
  willHide() {
    this._request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this._refreshRemoteAddress, this);
    this._request.removeEventListener(
        SDK.NetworkRequest.Events.RequestHeadersChanged, this._refreshRequestHeaders, this);
    this._request.removeEventListener(
        SDK.NetworkRequest.Events.ResponseHeadersChanged, this._refreshResponseHeaders, this);
    this._request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this._refreshHTTPInformation, this);
  }

  /**
   * @param {string} name
   * @param {string} value
   * @return {!DocumentFragment}
   */
  _formatHeader(name, value) {
    const fragment = createDocumentFragment();
    fragment.createChild('div', 'header-name').textContent = name + ': ';
    fragment.createChild('span', 'header-separator');
    fragment.createChild('div', 'header-value source-code').textContent = value;

    return fragment;
  }

  /**
   * @param {string} value
   * @param {string} className
   * @param {boolean} decodeParameters
   * @return {!Element}
   */
  _formatParameter(value, className, decodeParameters) {
    let errorDecoding = false;

    if (decodeParameters) {
      value = value.replace(/\+/g, ' ');
      if (value.indexOf('%') >= 0) {
        try {
          value = decodeURIComponent(value);
        } catch (e) {
          errorDecoding = true;
        }
      }
    }
    const div = createElementWithClass('div', className);
    if (value === '') {
      div.classList.add('empty-value');
    }
    if (errorDecoding) {
      div.createChild('span', 'header-decode-error').textContent = Common.UIString('(unable to decode value)');
    } else {
      div.textContent = value;
    }
    return div;
  }

  _refreshURL() {
    this._urlItem.title = this._formatHeader(Common.UIString('Request URL'), this._request.url());
  }

  _refreshQueryString() {
    const queryString = this._request.queryString();
    const queryParameters = this._request.queryParameters;
    this._queryStringCategory.hidden = !queryParameters;
    if (queryParameters) {
      this._refreshParams(
          Common.UIString('Query String Parameters'), queryParameters, queryString, this._queryStringCategory);
    }
  }

  async _refreshFormData() {
    this._formDataCategory.hidden = true;
    this._requestPayloadCategory.hidden = true;

    const formData = await this._request.requestFormData();
    if (!formData) {
      return;
    }

    const formParameters = await this._request.formParameters();
    if (formParameters) {
      this._formDataCategory.hidden = false;
      this._refreshParams(Common.UIString('Form Data'), formParameters, formData, this._formDataCategory);
    } else {
      this._requestPayloadCategory.hidden = false;
      try {
        const json = JSON.parse(formData);
        this._refreshRequestJSONPayload(json, formData);
      } catch (e) {
        this._populateTreeElementWithSourceText(this._requestPayloadCategory, formData);
      }
    }
  }

  /**
   * @param {!UI.TreeElement} treeElement
   * @param {?string} sourceText
   */
  _populateTreeElementWithSourceText(treeElement, sourceText) {
    const max_len = 3000;
    const text = (sourceText || '').trim();
    const trim = text.length > max_len;

    const sourceTextElement = createElementWithClass('span', 'header-value source-code');
    sourceTextElement.textContent = trim ? text.substr(0, max_len) : text;

    const sourceTreeElement = new UI.TreeElement(sourceTextElement);
    treeElement.removeChildren();
    treeElement.appendChild(sourceTreeElement);
    if (!trim) {
      return;
    }

    const showMoreButton = createElementWithClass('button', 'request-headers-show-more-button');
    showMoreButton.textContent = Common.UIString('Show more');

    function showMore() {
      showMoreButton.remove();
      sourceTextElement.textContent = text;
      sourceTreeElement.listItemElement.removeEventListener('contextmenu', onContextMenuShowMore);
    }
    showMoreButton.addEventListener('click', showMore);

    /**
     * @param {!Event} event
     */
    function onContextMenuShowMore(event) {
      const contextMenu = new UI.ContextMenu(event);
      const section = contextMenu.newSection();
      section.appendItem(ls`Show more`, showMore);
      contextMenu.show();
    }
    sourceTreeElement.listItemElement.addEventListener('contextmenu', onContextMenuShowMore);
    sourceTextElement.appendChild(showMoreButton);
  }

  /**
   * @param {string} title
   * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
   * @param {?string} sourceText
   * @param {!UI.TreeElement} paramsTreeElement
   */
  _refreshParams(title, params, sourceText, paramsTreeElement) {
    paramsTreeElement.removeChildren();

    paramsTreeElement.listItemElement.removeChildren();
    paramsTreeElement.listItemElement.createChild('div', 'selection fill');
    paramsTreeElement.listItemElement.createTextChild(title);

    const headerCount = createElementWithClass('span', 'header-count');
    headerCount.textContent = Common.UIString('\xA0(%d)', params.length);
    paramsTreeElement.listItemElement.appendChild(headerCount);

    const shouldViewSource = paramsTreeElement[_viewSourceSymbol];
    if (shouldViewSource) {
      this._appendParamsSource(title, params, sourceText, paramsTreeElement);
    } else {
      this._appendParamsParsed(title, params, sourceText, paramsTreeElement);
    }
  }

  /**
   * @param {string} title
   * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
   * @param {?string} sourceText
   * @param {!UI.TreeElement} paramsTreeElement
   */
  _appendParamsSource(title, params, sourceText, paramsTreeElement) {
    this._populateTreeElementWithSourceText(paramsTreeElement, sourceText);

    const listItemElement = paramsTreeElement.listItemElement;

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewParsed = function(event) {
      listItemElement.removeEventListener('contextmenu', viewParsedContextMenu);

      paramsTreeElement[_viewSourceSymbol] = false;
      this._refreshParams(title, params, sourceText, paramsTreeElement);
      event.consume();
    };

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewParsedContextMenu = function(event) {
      if (!paramsTreeElement.expanded) {
        return;
      }
      const contextMenu = new UI.ContextMenu(event);
      contextMenu.newSection().appendItem(ls`View parsed`, viewParsed.bind(this, event));
      contextMenu.show();
    }.bind(this);

    const viewParsedButton = this._createViewSourceToggle(/* viewSource */ true, viewParsed.bind(this));
    listItemElement.appendChild(viewParsedButton);

    listItemElement.addEventListener('contextmenu', viewParsedContextMenu);
  }

  /**
   * @param {string} title
   * @param {?Array.<!SDK.NetworkRequest.NameValue>} params
   * @param {?string} sourceText
   * @param {!UI.TreeElement} paramsTreeElement
   */
  _appendParamsParsed(title, params, sourceText, paramsTreeElement) {
    for (let i = 0; i < params.length; ++i) {
      const paramNameValue = createDocumentFragment();
      if (params[i].name !== '') {
        const name = this._formatParameter(params[i].name + ': ', 'header-name', this._decodeRequestParameters);
        const value = this._formatParameter(params[i].value, 'header-value source-code', this._decodeRequestParameters);
        paramNameValue.appendChild(name);
        paramNameValue.createChild('span', 'header-separator');
        paramNameValue.appendChild(value);
      } else {
        paramNameValue.appendChild(
            this._formatParameter(Common.UIString('(empty)'), 'empty-request-header', this._decodeRequestParameters));
      }

      const paramTreeElement = new UI.TreeElement(paramNameValue);
      paramsTreeElement.appendChild(paramTreeElement);
    }

    const listItemElement = paramsTreeElement.listItemElement;

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewSource = function(event) {
      listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);

      paramsTreeElement[_viewSourceSymbol] = true;
      this._refreshParams(title, params, sourceText, paramsTreeElement);
      event.consume();
    };

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const toggleURLDecoding = function(event) {
      listItemElement.removeEventListener('contextmenu', viewSourceContextMenu);
      this._toggleURLDecoding(event);
    };

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewSourceContextMenu = function(event) {
      if (!paramsTreeElement.expanded) {
        return;
      }
      const contextMenu = new UI.ContextMenu(event);
      const section = contextMenu.newSection();
      section.appendItem(ls`View source`, viewSource.bind(this, event));
      const viewURLEncodedText = this._decodeRequestParameters ? ls`View URL encoded` : ls`View decoded`;
      section.appendItem(viewURLEncodedText, toggleURLDecoding.bind(this, event));
      contextMenu.show();
    }.bind(this);

    const viewSourceButton = this._createViewSourceToggle(/* viewSource */ false, viewSource.bind(this));
    listItemElement.appendChild(viewSourceButton);

    const toggleTitle = this._decodeRequestParameters ? ls`view URL encoded` : ls`view decoded`;
    const toggleButton = this._createToggleButton(toggleTitle);
    toggleButton.addEventListener('click', toggleURLDecoding.bind(this), false);
    listItemElement.appendChild(toggleButton);

    listItemElement.addEventListener('contextmenu', viewSourceContextMenu);
  }

  /**
   * @param {*} parsedObject
   * @param {string} sourceText
   */
  _refreshRequestJSONPayload(parsedObject, sourceText) {
    const rootListItem = this._requestPayloadCategory;
    rootListItem.removeChildren();

    const rootListItemElement = rootListItem.listItemElement;
    rootListItemElement.removeChildren();
    rootListItemElement.createChild('div', 'selection fill');
    rootListItemElement.createTextChild(this._requestPayloadCategory.title);

    const shouldViewSource = rootListItem[_viewSourceSymbol];
    if (shouldViewSource) {
      this._appendJSONPayloadSource(rootListItem, parsedObject, sourceText);
    } else {
      this._appendJSONPayloadParsed(rootListItem, parsedObject, sourceText);
    }
  }

  /**
   * @param {!Category} rootListItem
   * @param {*} parsedObject
   * @param {string} sourceText
   */
  _appendJSONPayloadSource(rootListItem, parsedObject, sourceText) {
    const rootListItemElement = rootListItem.listItemElement;
    this._populateTreeElementWithSourceText(rootListItem, sourceText);

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewParsed = function(event) {
      rootListItemElement.removeEventListener('contextmenu', viewParsedContextMenu);
      rootListItem[_viewSourceSymbol] = false;
      this._refreshRequestJSONPayload(parsedObject, sourceText);
      event.consume();
    };

    const viewParsedButton = this._createViewSourceToggle(/* viewSource */ true, viewParsed.bind(this));
    rootListItemElement.appendChild(viewParsedButton);

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewParsedContextMenu = function(event) {
      if (!rootListItem.expanded) {
        return;
      }
      const contextMenu = new UI.ContextMenu(event);
      contextMenu.newSection().appendItem(ls`View parsed`, viewParsed.bind(this, event));
      contextMenu.show();
    }.bind(this);

    rootListItemElement.addEventListener('contextmenu', viewParsedContextMenu);
  }

  /**
   * @param {!Category} rootListItem
   * @param {*} parsedObject
   * @param {string} sourceText
   */
  _appendJSONPayloadParsed(rootListItem, parsedObject, sourceText) {
    const object = /** @type {!SDK.LocalJSONObject} */ (SDK.RemoteObject.fromLocalObject(parsedObject));
    const section = new ObjectUI.ObjectPropertiesSection.RootElement(object);
    section.title = object.description;
    section.expand();
    section.editable = false;
    rootListItem.childrenListElement.classList.add('source-code', 'object-properties-section');

    rootListItem.appendChild(section);
    const rootListItemElement = rootListItem.listItemElement;

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewSource = function(event) {
      rootListItemElement.removeEventListener('contextmenu', viewSourceContextMenu);

      rootListItem[_viewSourceSymbol] = true;
      this._refreshRequestJSONPayload(parsedObject, sourceText);
      event.consume();
    };

    /**
     * @param {!Event} event
     * @this {RequestHeadersView}
     */
    const viewSourceContextMenu = function(event) {
      if (!rootListItem.expanded) {
        return;
      }
      const contextMenu = new UI.ContextMenu(event);
      contextMenu.newSection().appendItem(ls`View source`, viewSource.bind(this, event));
      contextMenu.show();
    }.bind(this);

    const viewSourceButton = this._createViewSourceToggle(/* viewSource */ false, viewSource.bind(this));
    rootListItemElement.appendChild(viewSourceButton);

    rootListItemElement.addEventListener('contextmenu', viewSourceContextMenu);
  }

  /**
   * @param {boolean} viewSource
   * @param {function(!Event)} handler
   * @return {!Element}
   */
  _createViewSourceToggle(viewSource, handler) {
    const viewSourceToggleTitle = viewSource ? Common.UIString('view parsed') : Common.UIString('view source');
    const viewSourceToggleButton = this._createToggleButton(viewSourceToggleTitle);
    viewSourceToggleButton.addEventListener('click', handler, false);
    return viewSourceToggleButton;
  }

  /**
   * @param {!Event} event
   */
  _toggleURLDecoding(event) {
    this._decodeRequestParameters = !this._decodeRequestParameters;
    this._refreshQueryString();
    this._refreshFormData();
    event.consume();
  }

  _refreshRequestHeaders() {
    const treeElement = this._requestHeadersCategory;
    const headers = this._request.requestHeaders().slice();
    headers.sort(function(a, b) {
      return a.name.toLowerCase().compareTo(b.name.toLowerCase());
    });
    const headersText = this._request.requestHeadersText();

    if (this._showRequestHeadersText && headersText) {
      this._refreshHeadersText(Common.UIString('Request Headers'), headers.length, headersText, treeElement);
    } else {
      this._refreshHeaders(Common.UIString('Request Headers'), headers, treeElement, headersText === undefined);
    }

    if (headersText) {
      const toggleButton = this._createHeadersToggleButton(this._showRequestHeadersText);
      toggleButton.addEventListener('click', this._toggleRequestHeadersText.bind(this), false);
      treeElement.listItemElement.appendChild(toggleButton);
    }

    this._refreshFormData();
  }

  _refreshResponseHeaders() {
    const treeElement = this._responseHeadersCategory;
    const headers = this._request.sortedResponseHeaders.slice();
    const headersText = this._request.responseHeadersText;

    if (this._showResponseHeadersText) {
      this._refreshHeadersText(Common.UIString('Response Headers'), headers.length, headersText, treeElement);
    } else {
      this._refreshHeaders(
          Common.UIString('Response Headers'), headers, treeElement, /* provisional */ false,
          this._request.blockedResponseCookies());
    }

    if (headersText) {
      const toggleButton = this._createHeadersToggleButton(this._showResponseHeadersText);
      toggleButton.addEventListener('click', this._toggleResponseHeadersText.bind(this), false);
      treeElement.listItemElement.appendChild(toggleButton);
    }
  }

  _refreshHTTPInformation() {
    const requestMethodElement = this._requestMethodItem;
    requestMethodElement.hidden = !this._request.statusCode;
    const statusCodeElement = this._statusCodeItem;
    statusCodeElement.hidden = !this._request.statusCode;

    if (this._request.statusCode) {
      const statusCodeFragment = createDocumentFragment();
      statusCodeFragment.createChild('div', 'header-name').textContent = ls`Status Code` +
          ': ';
      statusCodeFragment.createChild('span', 'header-separator');

      const statusCodeImage = statusCodeFragment.createChild('span', 'resource-status-image', 'dt-icon-label');
      statusCodeImage.title = this._request.statusCode + ' ' + this._request.statusText;

      if (this._request.statusCode < 300 || this._request.statusCode === 304) {
        statusCodeImage.type = 'smallicon-green-ball';
      } else if (this._request.statusCode < 400) {
        statusCodeImage.type = 'smallicon-orange-ball';
      } else {
        statusCodeImage.type = 'smallicon-red-ball';
      }

      requestMethodElement.title = this._formatHeader(ls`Request Method`, this._request.requestMethod);

      const statusTextElement = statusCodeFragment.createChild('div', 'header-value source-code');
      let statusText = this._request.statusCode + ' ' + this._request.statusText;
      if (this._request.cachedInMemory()) {
        statusText += ' ' + ls`(from memory cache)`;
        statusTextElement.classList.add('status-from-cache');
      } else if (this._request.fetchedViaServiceWorker) {
        statusText += ' ' + ls`(from ServiceWorker)`;
        statusTextElement.classList.add('status-from-cache');
      } else if (
          this._request.redirectSource() && this._request.redirectSource().signedExchangeInfo() &&
          !this._request.redirectSource().signedExchangeInfo().errors) {
        statusText += ' ' + ls`(from signed-exchange)`;
        statusTextElement.classList.add('status-from-cache');
      } else if (this._request.fromPrefetchCache()) {
        statusText += ' ' + ls`(from prefetch cache)`;
        statusTextElement.classList.add('status-from-cache');
      } else if (this._request.cached()) {
        statusText += ' ' + ls`(from disk cache)`;
        statusTextElement.classList.add('status-from-cache');
      }
      statusTextElement.textContent = statusText;

      statusCodeElement.title = statusCodeFragment;
    }
  }

  /**
   * @param {string} title
   * @param {!UI.TreeElement} headersTreeElement
   * @param {number} headersLength
   */
  _refreshHeadersTitle(title, headersTreeElement, headersLength) {
    headersTreeElement.listItemElement.removeChildren();
    headersTreeElement.listItemElement.createChild('div', 'selection fill');
    headersTreeElement.listItemElement.createTextChild(title);

    const headerCount = Common.UIString('\xA0(%d)', headersLength);
    headersTreeElement.listItemElement.createChild('span', 'header-count').textContent = headerCount;
  }

  /**
   * @param {string} title
   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
   * @param {!UI.TreeElement} headersTreeElement
   * @param {boolean=} provisionalHeaders
   * @param {!Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>=} blockedResponseCookies
   */
  _refreshHeaders(title, headers, headersTreeElement, provisionalHeaders, blockedResponseCookies) {
    headersTreeElement.removeChildren();

    const length = headers.length;
    this._refreshHeadersTitle(title, headersTreeElement, length);

    if (provisionalHeaders) {
      const cautionText = Common.UIString('Provisional headers are shown');
      const cautionFragment = createDocumentFragment();
      cautionFragment.createChild('span', '', 'dt-icon-label').type = 'smallicon-warning';
      cautionFragment.createChild('div', 'caution').textContent = cautionText;
      const cautionTreeElement = new UI.TreeElement(cautionFragment);
      headersTreeElement.appendChild(cautionTreeElement);
    }

    /** @type {!Map<string, !Array<!Protocol.Network.SetCookieBlockedReason>>} */
    const blockedCookieLineToReasons = new Map();
    if (blockedResponseCookies) {
      blockedResponseCookies.forEach(blockedCookie => {
        blockedCookieLineToReasons.set(blockedCookie.cookieLine, blockedCookie.blockedReasons);
      });
    }

    headersTreeElement.hidden = !length && !provisionalHeaders;
    for (let i = 0; i < length; ++i) {
      const headerTreeElement = new UI.TreeElement(this._formatHeader(headers[i].name, headers[i].value));
      headerTreeElement[_headerNameSymbol] = headers[i].name;

      if (headers[i].name.toLowerCase() === 'set-cookie') {
        const matchingBlockedReasons = blockedCookieLineToReasons.get(headers[i].value);
        if (matchingBlockedReasons) {
          const icon = UI.Icon.create('smallicon-warning', '');
          headerTreeElement.listItemElement.appendChild(icon);

          let titleText = '';
          for (const blockedReason of matchingBlockedReasons) {
            if (titleText) {
              titleText += '\n';
            }
            titleText += SDK.NetworkRequest.setCookieBlockedReasonToUiString(blockedReason);
          }
          icon.title = titleText;
        }
      }

      headersTreeElement.appendChild(headerTreeElement);
    }
  }

  /**
   * @param {string} title
   * @param {number} count
   * @param {string} headersText
   * @param {!UI.TreeElement} headersTreeElement
   */
  _refreshHeadersText(title, count, headersText, headersTreeElement) {
    this._populateTreeElementWithSourceText(headersTreeElement, headersText);
    this._refreshHeadersTitle(title, headersTreeElement, count);
  }

  _refreshRemoteAddress() {
    const remoteAddress = this._request.remoteAddress();
    const treeElement = this._remoteAddressItem;
    treeElement.hidden = !remoteAddress;
    if (remoteAddress) {
      treeElement.title = this._formatHeader(Common.UIString('Remote Address'), remoteAddress);
    }
  }

  _refreshReferrerPolicy() {
    const referrerPolicy = this._request.referrerPolicy();
    const treeElement = this._referrerPolicyItem;
    treeElement.hidden = !referrerPolicy;
    if (referrerPolicy) {
      treeElement.title = this._formatHeader(Common.UIString('Referrer Policy'), referrerPolicy);
    }
  }

  /**
   * @param {!Event} event
   */
  _toggleRequestHeadersText(event) {
    this._showRequestHeadersText = !this._showRequestHeadersText;
    this._refreshRequestHeaders();
    event.consume();
  }

  /**
   * @param {!Event} event
   */
  _toggleResponseHeadersText(event) {
    this._showResponseHeadersText = !this._showResponseHeadersText;
    this._refreshResponseHeaders();
    event.consume();
  }

  /**
   * @param {string} title
   * @return {!Element}
   */
  _createToggleButton(title) {
    const button = createElementWithClass('span', 'header-toggle');
    button.textContent = title;
    return button;
  }

  /**
   * @param {boolean} isHeadersTextShown
   * @return {!Element}
   */
  _createHeadersToggleButton(isHeadersTextShown) {
    const toggleTitle = isHeadersTextShown ? Common.UIString('view parsed') : Common.UIString('view source');
    return this._createToggleButton(toggleTitle);
  }

  _clearHighlight() {
    if (this._highlightedElement) {
      this._highlightedElement.listItemElement.classList.remove('header-highlight');
    }
    this._highlightedElement = null;
  }


  /**
   * @param {?UI.TreeElement} category
   * @param {string} name
   */
  _revealAndHighlight(category, name) {
    this._clearHighlight();
    for (const element of category.children()) {
      if (element[_headerNameSymbol] !== name) {
        continue;
      }
      this._highlightedElement = element;
      element.reveal();
      element.listItemElement.classList.add('header-highlight');
      return;
    }
  }

  /**
   * @param {string} header
   */
  revealRequestHeader(header) {
    this._revealAndHighlight(this._requestHeadersCategory, header);
  }

  /**
   * @param {string} header
   */
  revealResponseHeader(header) {
    this._revealAndHighlight(this._responseHeadersCategory, header);
  }
}

export const _headerNameSymbol = Symbol('HeaderName');
export const _viewSourceSymbol = Symbol('ViewSource');

/**
 * @unrestricted
 */
export class Category extends UI.TreeElement {
  /**
   * @param {!UI.TreeOutline} root
   * @param {string} name
   * @param {string=} title
   */
  constructor(root, name, title) {
    super(title || '', true);
    this.toggleOnClick = true;
    this.hidden = true;
    this._expandedSetting = Common.settings.createSetting('request-info-' + name + '-category-expanded', true);
    this.expanded = this._expandedSetting.get();
    root.appendChild(this);
  }

  /**
   * @return {!UI.TreeElement}
   */
  createLeaf() {
    const leaf = new UI.TreeElement();
    this.appendChild(leaf);
    return leaf;
  }

  /**
   * @override
   */
  onexpand() {
    this._expandedSetting.set(true);
  }

  /**
   * @override
   */
  oncollapse() {
    this._expandedSetting.set(false);
  }
}

/* Legacy exported object */
self.Network = self.Network || {};

/* Legacy exported object */
Network = Network || {};

/**
 * @constructor
 */
Network.RequestHeadersView = RequestHeadersView;

Network.RequestHeadersView._headerNameSymbol = _headerNameSymbol;
Network.RequestHeadersView._viewSourceSymbol = _viewSourceSymbol;

/**
 * @constructor
 */
Network.RequestHeadersView.Category = Category;
