// Copyright 2015 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.
/**
 * @implements {SDK.SDKModelObserver<!Security.SecurityModel>}
 * @unrestricted
 */
export default class SecurityPanel extends UI.PanelWithSidebar {
  constructor() {
    super('security');

    this._mainView = new Security.SecurityMainView(this);

    const title = createElementWithClass('span', 'title');
    title.textContent = Common.UIString('Overview');
    this._sidebarMainViewElement = new Security.SecurityPanelSidebarTreeElement(
        title, this._setVisibleView.bind(this, this._mainView), 'security-main-view-sidebar-tree-item', 'lock-icon');
    this._sidebarMainViewElement.tooltip = title.textContent;
    this._sidebarTree = new Security.SecurityPanelSidebarTree(this._sidebarMainViewElement, this.showOrigin.bind(this));
    this.panelSidebarElement().appendChild(this._sidebarTree.element);

    /** @type {!Map<!Protocol.Network.LoaderId, !SDK.NetworkRequest>} */
    this._lastResponseReceivedForLoaderId = new Map();

    /** @type {!Map<!Security.SecurityPanel.Origin, !Security.SecurityPanel.OriginState>} */
    this._origins = new Map();

    /** @type {!Map<!Network.NetworkLogView.MixedContentFilterValues, number>} */
    this._filterRequestCounts = new Map();

    SDK.targetManager.observeModels(Security.SecurityModel, this);
  }

  /**
   * @return {!Security.SecurityPanel}
   */
  static _instance() {
    return /** @type {!Security.SecurityPanel} */ (self.runtime.sharedInstance(Security.SecurityPanel));
  }

  /**
   * @param {string} text
   * @param {string} origin
   * @return {!Element}
   */
  static createCertificateViewerButtonForOrigin(text, origin) {
    const certificateButton = UI.createTextButton(text, async e => {
      e.consume();
      const names = await SDK.multitargetNetworkManager.getCertificate(origin);
      if (names.length > 0) {
        Host.InspectorFrontendHost.showCertificateViewer(names);
      }
    }, 'origin-button');
    UI.ARIAUtils.markAsButton(certificateButton);
    return certificateButton;
  }

  /**
   * @param {string} text
   * @param {!Array<string>} names
   * @return {!Element}
   */
  static createCertificateViewerButtonForCert(text, names) {
    const certificateButton = UI.createTextButton(text, e => {
      e.consume();
      Host.InspectorFrontendHost.showCertificateViewer(names);
    }, 'origin-button');
    UI.ARIAUtils.markAsButton(certificateButton);
    return certificateButton;
  }

  /**
   * @param {string} url
   * @param {string} securityState
   * @return {!Element}
   */
  static createHighlightedUrl(url, securityState) {
    const schemeSeparator = '://';
    const index = url.indexOf(schemeSeparator);

    // If the separator is not found, just display the text without highlighting.
    if (index === -1) {
      const text = createElement('span', '');
      text.textContent = url;
      return text;
    }

    const highlightedUrl = createElement('span');

    const scheme = url.substr(0, index);
    const content = url.substr(index + schemeSeparator.length);
    highlightedUrl.createChild('span', 'url-scheme-' + securityState).textContent = scheme;
    highlightedUrl.createChild('span', 'url-scheme-separator').textContent = schemeSeparator;
    highlightedUrl.createChild('span').textContent = content;

    return highlightedUrl;
  }

  /**
   * @param {!Protocol.Security.SecurityState} newSecurityState
   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
   * @param {?string} summary
   */
  _updateSecurityState(newSecurityState, explanations, summary) {
    this._sidebarMainViewElement.setSecurityState(newSecurityState);
    this._mainView.updateSecurityState(newSecurityState, explanations, summary);
  }

  /**
   * @param {!Common.Event} event
   */
  _onSecurityStateChanged(event) {
    const data = /** @type {!Security.PageSecurityState} */ (event.data);
    const securityState = /** @type {!Protocol.Security.SecurityState} */ (data.securityState);
    const explanations = /** @type {!Array<!Protocol.Security.SecurityStateExplanation>} */ (data.explanations);
    const summary = /** @type {?string} */ (data.summary);
    this._updateSecurityState(securityState, explanations, summary);
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   */
  _updateVisibleSecurityState(visibleSecurityState) {
    this._sidebarMainViewElement.setSecurityState(visibleSecurityState.securityState);
    this._mainView.updateVisibleSecurityState(visibleSecurityState);
  }

  /**
   * @param {!Common.Event} event
   */
  _onVisibleSecurityStateChanged(event) {
    const data = /** @type {!Security.PageVisibleSecurityState} */ (event.data);
    this._updateVisibleSecurityState(data);
  }

  selectAndSwitchToMainView() {
    // The sidebar element will trigger displaying the main view. Rather than making a redundant call to display the main view, we rely on this.
    this._sidebarMainViewElement.select(true);
  }
  /**
   * @param {!Security.SecurityPanel.Origin} origin
   */
  showOrigin(origin) {
    const originState = this._origins.get(origin);
    if (!originState.originView) {
      originState.originView = new Security.SecurityOriginView(this, origin, originState);
    }

    this._setVisibleView(originState.originView);
  }

  /**
   * @override
   */
  wasShown() {
    super.wasShown();
    if (!this._visibleView) {
      this.selectAndSwitchToMainView();
    }
  }

  /**
   * @override
   */
  focus() {
    this._sidebarTree.focus();
  }

  /**
   * @param {!UI.VBox} view
   */
  _setVisibleView(view) {
    if (this._visibleView === view) {
      return;
    }

    if (this._visibleView) {
      this._visibleView.detach();
    }

    this._visibleView = view;

    if (view) {
      this.splitWidget().setMainWidget(view);
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _onResponseReceived(event) {
    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
    if (request.resourceType() === Common.resourceTypes.Document) {
      this._lastResponseReceivedForLoaderId.set(request.loaderId, request);
    }
  }

  /**
   * @param {!SDK.NetworkRequest} request
   */
  _processRequest(request) {
    const origin = Common.ParsedURL.extractOrigin(request.url());

    if (!origin) {
      // We don't handle resources like data: URIs. Most of them don't affect the lock icon.
      return;
    }

    let securityState = /** @type {!Protocol.Security.SecurityState} */ (request.securityState());

    if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable ||
        request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
      securityState = Protocol.Security.SecurityState.Insecure;
    }

    if (this._origins.has(origin)) {
      const originState = this._origins.get(origin);
      const oldSecurityState = originState.securityState;
      originState.securityState = this._securityStateMin(oldSecurityState, securityState);
      if (oldSecurityState !== originState.securityState) {
        const securityDetails = /** @type {?Protocol.Network.SecurityDetails} */ (request.securityDetails());
        if (securityDetails) {
          originState.securityDetails = securityDetails;
        }
        this._sidebarTree.updateOrigin(origin, securityState);
        if (originState.originView) {
          originState.originView.setSecurityState(securityState);
        }
      }
    } else {
      // This stores the first security details we see for an origin, but we should
      // eventually store a (deduplicated) list of all the different security
      // details we have seen. https://crbug.com/503170
      const originState = {};
      originState.securityState = securityState;

      const securityDetails = request.securityDetails();
      if (securityDetails) {
        originState.securityDetails = securityDetails;
      }

      originState.loadedFromCache = request.cached();

      this._origins.set(origin, originState);

      this._sidebarTree.addOrigin(origin, securityState);

      // Don't construct the origin view yet (let it happen lazily).
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _onRequestFinished(event) {
    const request = /** @type {!SDK.NetworkRequest} */ (event.data);
    this._updateFilterRequestCounts(request);
    this._processRequest(request);
  }

  /**
   * @param {!SDK.NetworkRequest} request
   */
  _updateFilterRequestCounts(request) {
    if (request.mixedContentType === Protocol.Security.MixedContentType.None) {
      return;
    }

    /** @type {!Network.NetworkLogView.MixedContentFilterValues} */
    let filterKey = Network.NetworkLogView.MixedContentFilterValues.All;
    if (request.wasBlocked()) {
      filterKey = Network.NetworkLogView.MixedContentFilterValues.Blocked;
    } else if (request.mixedContentType === Protocol.Security.MixedContentType.Blockable) {
      filterKey = Network.NetworkLogView.MixedContentFilterValues.BlockOverridden;
    } else if (request.mixedContentType === Protocol.Security.MixedContentType.OptionallyBlockable) {
      filterKey = Network.NetworkLogView.MixedContentFilterValues.Displayed;
    }

    if (!this._filterRequestCounts.has(filterKey)) {
      this._filterRequestCounts.set(filterKey, 1);
    } else {
      this._filterRequestCounts.set(filterKey, this._filterRequestCounts.get(filterKey) + 1);
    }

    this._mainView.refreshExplanations();
  }

  /**
   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
   * @return {number}
   */
  filterRequestCount(filterKey) {
    return this._filterRequestCounts.get(filterKey) || 0;
  }

  /**
   * @param {!Protocol.Security.SecurityState} stateA
   * @param {!Protocol.Security.SecurityState} stateB
   * @return {!Protocol.Security.SecurityState}
   */
  _securityStateMin(stateA, stateB) {
    return Security.SecurityModel.SecurityStateComparator(stateA, stateB) < 0 ? stateA : stateB;
  }

  /**
   * @override
   * @param {!Security.SecurityModel} securityModel
   */
  modelAdded(securityModel) {
    if (this._securityModel) {
      return;
    }

    this._securityModel = securityModel;
    const resourceTreeModel = securityModel.resourceTreeModel();
    const networkManager = securityModel.networkManager();
    this._eventListeners = [
      securityModel.addEventListener(
          Security.SecurityModel.Events.VisibleSecurityStateChanged, this._onVisibleSecurityStateChanged, this),
      resourceTreeModel.addEventListener(
          SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this),
      resourceTreeModel.addEventListener(
          SDK.ResourceTreeModel.Events.InterstitialShown, this._onInterstitialShown, this),
      resourceTreeModel.addEventListener(
          SDK.ResourceTreeModel.Events.InterstitialHidden, this._onInterstitialHidden, this),
      networkManager.addEventListener(SDK.NetworkManager.Events.ResponseReceived, this._onResponseReceived, this),
      networkManager.addEventListener(SDK.NetworkManager.Events.RequestFinished, this._onRequestFinished, this),
    ];

    if (resourceTreeModel.isInterstitialShowing()) {
      this._onInterstitialShown();
    }
  }

  /**
   * @override
   * @param {!Security.SecurityModel} securityModel
   */
  modelRemoved(securityModel) {
    if (this._securityModel !== securityModel) {
      return;
    }

    delete this._securityModel;
    Common.EventTarget.removeEventListeners(this._eventListeners);
  }

  /**
   * @param {!Common.Event} event
   */
  _onMainFrameNavigated(event) {
    const frame = /** type {!Protocol.Page.Frame}*/ (event.data);
    const request = this._lastResponseReceivedForLoaderId.get(frame.loaderId);

    this.selectAndSwitchToMainView();
    this._sidebarTree.clearOrigins();
    this._origins.clear();
    this._lastResponseReceivedForLoaderId.clear();
    this._filterRequestCounts.clear();
    // After clearing the filtered request counts, refresh the
    // explanations to reflect the new counts.
    this._mainView.refreshExplanations();

    // If we could not find a matching request (as in the case of clicking
    // through an interstitial, see https://crbug.com/669309), set the origin
    // based upon the url data from the MainFrameNavigated event itself.
    const origin = Common.ParsedURL.extractOrigin(request ? request.url() : frame.url);
    this._sidebarTree.setMainOrigin(origin);

    if (request) {
      this._processRequest(request);
    }
  }

  _onInterstitialShown() {
    // The panel might have been displaying the origin view on the
    // previously loaded page. When showing an interstitial, switch
    // back to the Overview view.
    this.selectAndSwitchToMainView();
    this._sidebarTree.toggleOriginsList(true /* hidden */);
  }

  _onInterstitialHidden() {
    this._sidebarTree.toggleOriginsList(false /* hidden */);
  }
}

/**
 * @unrestricted
 */
export class SecurityPanelSidebarTree extends UI.TreeOutlineInShadow {
  /**
   * @param {!Security.SecurityPanelSidebarTreeElement} mainViewElement
   * @param {function(!Security.SecurityPanel.Origin)} showOriginInPanel
   */
  constructor(mainViewElement, showOriginInPanel) {
    super();
    this.registerRequiredCSS('security/sidebar.css');
    this.registerRequiredCSS('security/lockIcon.css');
    this.appendChild(mainViewElement);

    this._showOriginInPanel = showOriginInPanel;
    this._mainOrigin = null;

    /** @type {!Map<!Security.SecurityPanelSidebarTree.OriginGroup, !UI.TreeElement>} */
    this._originGroups = new Map();

    /** @type {!Map<!Security.SecurityPanelSidebarTree.OriginGroup, string>} */
    this._originGroupTitles = new Map([
      [Security.SecurityPanelSidebarTree.OriginGroup.MainOrigin, ls`Main origin`],
      [Security.SecurityPanelSidebarTree.OriginGroup.NonSecure, ls`Non-secure origins`],
      [Security.SecurityPanelSidebarTree.OriginGroup.Secure, ls`Secure origins`],
      [Security.SecurityPanelSidebarTree.OriginGroup.Unknown, ls`Unknown / canceled`],
    ]);

    for (const key in Security.SecurityPanelSidebarTree.OriginGroup) {
      const group = Security.SecurityPanelSidebarTree.OriginGroup[key];
      const element = this._createOriginGroupElement(this._originGroupTitles.get(group));
      this._originGroups.set(group, element);
      this.appendChild(element);
    }

    this._clearOriginGroups();

    // This message will be removed by clearOrigins() during the first new page load after the panel was opened.
    const mainViewReloadMessage = new UI.TreeElement(Common.UIString('Reload to view details'));
    mainViewReloadMessage.selectable = false;
    mainViewReloadMessage.listItemElement.classList.add('security-main-view-reload-message');
    this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.MainOrigin).appendChild(mainViewReloadMessage);

    /** @type {!Map<!Security.SecurityPanel.Origin, !Security.SecurityPanelSidebarTreeElement>} */
    this._elementsByOrigin = new Map();
  }

  /**
   * @param {string} originGroupTitle
   * @return {!UI.TreeElement}
   */
  _createOriginGroupElement(originGroupTitle) {
    const originGroup = new UI.TreeElement(originGroupTitle, true);
    originGroup.selectable = false;
    originGroup.setCollapsible(false);
    originGroup.expand();
    originGroup.listItemElement.classList.add('security-sidebar-origins');
    UI.ARIAUtils.setAccessibleName(originGroup.childrenListElement, originGroupTitle);
    return originGroup;
  }

  /**
   * @param {boolean} hidden
   */
  toggleOriginsList(hidden) {
    for (const element of this._originGroups.values()) {
      element.hidden = hidden;
    }
  }

  /**
   * @param {!Security.SecurityPanel.Origin} origin
   * @param {!Protocol.Security.SecurityState} securityState
   */
  addOrigin(origin, securityState) {
    const originElement = new Security.SecurityPanelSidebarTreeElement(
        Security.SecurityPanel.createHighlightedUrl(origin, securityState), this._showOriginInPanel.bind(this, origin),
        'security-sidebar-tree-item', 'security-property');
    originElement.tooltip = origin;
    this._elementsByOrigin.set(origin, originElement);
    this.updateOrigin(origin, securityState);
  }

  /**
   * @param {!Security.SecurityPanel.Origin} origin
   */
  setMainOrigin(origin) {
    this._mainOrigin = origin;
  }

  /**
   * @param {!Security.SecurityPanel.Origin} origin
   * @param {!Protocol.Security.SecurityState} securityState
   */
  updateOrigin(origin, securityState) {
    const originElement =
        /** @type {!Security.SecurityPanelSidebarTreeElement} */ (this._elementsByOrigin.get(origin));
    originElement.setSecurityState(securityState);

    let newParent;
    if (origin === this._mainOrigin) {
      newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.MainOrigin);
      if (securityState === Protocol.Security.SecurityState.Secure) {
        newParent.title = ls`Main origin (secure)`;
      } else {
        newParent.title = ls`Main origin (non-secure)`;
      }
      UI.ARIAUtils.setAccessibleName(newParent.childrenListElement, newParent.title);
    } else {
      switch (securityState) {
        case Protocol.Security.SecurityState.Secure:
          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.Secure);
          break;
        case Protocol.Security.SecurityState.Unknown:
          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.Unknown);
          break;
        default:
          newParent = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.NonSecure);
          break;
      }
    }

    const oldParent = originElement.parent;
    if (oldParent !== newParent) {
      if (oldParent) {
        oldParent.removeChild(originElement);
        if (oldParent.childCount() === 0) {
          oldParent.hidden = true;
        }
      }
      newParent.appendChild(originElement);
      newParent.hidden = false;
    }
  }

  _clearOriginGroups() {
    for (const originGroup of this._originGroups.values()) {
      originGroup.removeChildren();
      originGroup.hidden = true;
    }
    const mainOrigin = this._originGroups.get(Security.SecurityPanelSidebarTree.OriginGroup.MainOrigin);
    mainOrigin.title = this._originGroupTitles.get(Security.SecurityPanelSidebarTree.OriginGroup.MainOrigin);
    mainOrigin.hidden = false;
  }

  clearOrigins() {
    this._clearOriginGroups();
    this._elementsByOrigin.clear();
  }
}

/** @enum {symbol} */
export const OriginGroup = {
  MainOrigin: Symbol('MainOrigin'),
  NonSecure: Symbol('NonSecure'),
  Secure: Symbol('Secure'),
  Unknown: Symbol('Unknown')
};

/**
 * @unrestricted
 */
export class SecurityPanelSidebarTreeElement extends UI.TreeElement {
  /**
   * @param {!Element} textElement
   * @param {function()} selectCallback
   * @param {string} className
   * @param {string} cssPrefix
   */
  constructor(textElement, selectCallback, className, cssPrefix) {
    super('', false);
    this._selectCallback = selectCallback;
    this._cssPrefix = cssPrefix;
    this.listItemElement.classList.add(className);
    this._iconElement = this.listItemElement.createChild('div', 'icon');
    this._iconElement.classList.add(this._cssPrefix);
    this.listItemElement.appendChild(textElement);
    this.setSecurityState(Protocol.Security.SecurityState.Unknown);
  }

  /**
   * @param {!Security.SecurityPanelSidebarTreeElement} a
   * @param {!Security.SecurityPanelSidebarTreeElement} b
   * @return {number}
   */
  static SecurityStateComparator(a, b) {
    return Security.SecurityModel.SecurityStateComparator(a.securityState(), b.securityState());
  }

  /**
   * @param {!Protocol.Security.SecurityState} newSecurityState
   */
  setSecurityState(newSecurityState) {
    if (this._securityState) {
      this._iconElement.classList.remove(this._cssPrefix + '-' + this._securityState);
    }

    this._securityState = newSecurityState;
    this._iconElement.classList.add(this._cssPrefix + '-' + newSecurityState);
  }

  /**
   * @return {!Protocol.Security.SecurityState}
   */
  securityState() {
    return this._securityState;
  }

  /**
   * @override
   * @return {boolean}
   */
  onselect() {
    this._selectCallback();
    return true;
  }
}

/**
 * @unrestricted
 */
export class SecurityMainView extends UI.VBox {
  /**
   * @param {!Security.SecurityPanel} panel
   */
  constructor(panel) {
    super(true);
    this.registerRequiredCSS('security/mainView.css');
    this.registerRequiredCSS('security/lockIcon.css');
    this.setMinimumSize(200, 100);

    this.contentElement.classList.add('security-main-view');

    this._panel = panel;

    this._summarySection = this.contentElement.createChild('div', 'security-summary');

    // Info explanations should appear after all others.
    this._securityExplanationsMain =
        this.contentElement.createChild('div', 'security-explanation-list security-explanations-main');
    this._securityExplanationsExtra =
        this.contentElement.createChild('div', 'security-explanation-list security-explanations-extra');

    // Fill the security summary section.
    const summaryDiv = this._summarySection.createChild('div', 'security-summary-section-title');
    summaryDiv.textContent = ls`Security overview`;
    UI.ARIAUtils.markAsHeading(summaryDiv, 1);

    const lockSpectrum = this._summarySection.createChild('div', 'lock-spectrum');
    this._lockSpectrum = new Map([
      [Protocol.Security.SecurityState.Secure, lockSpectrum.createChild('div', 'lock-icon lock-icon-secure')],
      [Protocol.Security.SecurityState.Neutral, lockSpectrum.createChild('div', 'lock-icon lock-icon-neutral')],
      [Protocol.Security.SecurityState.Insecure, lockSpectrum.createChild('div', 'lock-icon lock-icon-insecure')],
    ]);
    this._lockSpectrum.get(Protocol.Security.SecurityState.Secure).title = Common.UIString('Secure');
    this._lockSpectrum.get(Protocol.Security.SecurityState.Neutral).title = Common.UIString('Info');
    this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).title = Common.UIString('Not secure');

    this._summarySection.createChild('div', 'triangle-pointer-container')
        .createChild('div', 'triangle-pointer-wrapper')
        .createChild('div', 'triangle-pointer');

    this._summaryText = this._summarySection.createChild('div', 'security-summary-text');
    UI.ARIAUtils.markAsHeading(this._summaryText, 2);
  }

  /**
   * @param {!Element} parent
   * @param {!Protocol.Security.SecurityStateExplanation} explanation
   * @return {!Element}
   */
  _addExplanation(parent, explanation) {
    const explanationSection = parent.createChild('div', 'security-explanation');
    explanationSection.classList.add('security-explanation-' + explanation.securityState);

    explanationSection.createChild('div', 'security-property')
        .classList.add('security-property-' + explanation.securityState);
    const text = explanationSection.createChild('div', 'security-explanation-text');

    const explanationHeader = text.createChild('div', 'security-explanation-title');

    if (explanation.title) {
      explanationHeader.createChild('span').textContent = explanation.title + ' - ';
      explanationHeader.createChild('span', 'security-explanation-title-' + explanation.securityState).textContent =
          explanation.summary;
    } else {
      explanationHeader.textContent = explanation.summary;
    }

    text.createChild('div').textContent = explanation.description;

    if (explanation.certificate.length) {
      text.appendChild(Security.SecurityPanel.createCertificateViewerButtonForCert(
          Common.UIString('View certificate'), explanation.certificate));
    }

    if (explanation.recommendations && explanation.recommendations.length) {
      const recommendationList = text.createChild('ul', 'security-explanation-recommendations');
      for (const recommendation of explanation.recommendations) {
        recommendationList.createChild('li').textContent = recommendation;
      }
    }
    return text;
  }

  /**
   * @param {!Protocol.Security.SecurityState} newSecurityState
   * @param {!Array<!Protocol.Security.SecurityStateExplanation>} explanations
   * @param {?string} summary
   */
  updateSecurityState(newSecurityState, explanations, summary) {
    // Remove old state.
    // It's safe to call this even when this._securityState is undefined.
    this._summarySection.classList.remove('security-summary-' + this._securityState);

    // Add new state.
    this._securityState = newSecurityState;

    this._summarySection.classList.add('security-summary-' + this._securityState);
    const summaryExplanationStrings = {
      'unknown': ls`The security of this page is unknown.`,
      'insecure': ls`This page is not secure.`,
      'neutral': ls`This page is not secure.`,
      'secure': ls`This page is secure (valid HTTPS).`,
      'insecure-broken': ls`This page is not secure (broken HTTPS).`
    };

    // Update the color and title of the triangle icon in the lock spectrum to
    // match the security state.
    if (this._securityState === Protocol.Security.SecurityState.Insecure) {
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.add('lock-icon-insecure');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.remove('lock-icon-insecure-broken');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).title = Common.UIString('Not secure');
    } else if (this._securityState === Protocol.Security.SecurityState.InsecureBroken) {
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.add('lock-icon-insecure-broken');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.remove('lock-icon-insecure');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).title = Common.UIString('Not secure (broken)');
    }

    // Use override summary if present, otherwise use base explanation
    this._summaryText.textContent = summary || summaryExplanationStrings[this._securityState];

    this._explanations = explanations;

    this.refreshExplanations();
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   */
  updateVisibleSecurityState(visibleSecurityState) {
    // Remove old state.
    // It's safe to call this even when this._securityState is undefined.
    this._summarySection.classList.remove('security-summary-' + this._securityState);

    // Add new state.
    this._securityState = visibleSecurityState.securityState;
    this._summarySection.classList.add('security-summary-' + this._securityState);

    // Update the color and title of the triangle icon in the lock spectrum to
    // match the security state.
    if (this._securityState === Protocol.Security.SecurityState.Insecure) {
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.add('lock-icon-insecure');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.remove('lock-icon-insecure-broken');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).title = ls`Not secure`;
    } else if (this._securityState === Protocol.Security.SecurityState.InsecureBroken) {
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.add('lock-icon-insecure-broken');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).classList.remove('lock-icon-insecure');
      this._lockSpectrum.get(Protocol.Security.SecurityState.Insecure).title = ls`Not secure (broken)`;
    }

    const {summary, explanations} = this._getSecuritySummaryAndExplanations(visibleSecurityState);
    // Use override summary if present, otherwise use base explanation
    this._summaryText.textContent = summary || Security.SummaryMessages[this._securityState];

    this._explanations = this._orderExplanations(explanations);

    this.refreshExplanations();
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   * @returns {!{summary: (string|undefined), explanations: !Array<Security.SecurityStyleExplanation>}}
   */
  _getSecuritySummaryAndExplanations(visibleSecurityState) {
    const {securityState, securityStateIssueIds} = visibleSecurityState;
    let summary;
    const explanations = [];
    summary = this._explainSafetyTipSecurity(visibleSecurityState, summary, explanations);
    if (securityStateIssueIds.includes('malicious-content')) {
      summary = ls`This page is dangerous (flagged by Google Safe Browsing).`;
      // Always insert SafeBrowsing explanation at the front.
      explanations.unshift(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Insecure, undefined, ls`Flagged by Google Safe Browsing`,
          ls`To check this page's status, visit g.co/safebrowsingstatus.`));
    } else if (
        securityStateIssueIds.includes('is-error-page') &&
        (visibleSecurityState.certificateSecurityState === null ||
         visibleSecurityState.certificateSecurityState.certificateNetworkError === null)) {
      summary = ls`This is an error page.`;
      // In the case of a non cert error page, we usually don't have a
      // certificate, connection, or content that needs to be explained, e.g. in
      // the case of a net error, so we can early return.
      return {summary, explanations};
    } else if (
        securityState === Protocol.Security.SecurityState.InsecureBroken &&
        securityStateIssueIds.includes('scheme-is-not-cryptographic')) {
      summary = summary || ls`This page is insecure (unencrypted HTTP).`;
      if (securityStateIssueIds.includes('insecure-input-events')) {
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Insecure, undefined, ls`Form field edited on a non-secure page`,
            ls`Data was entered in a field on a non-secure page. A warning has been added to the URL bar.`));
      }
    }

    if (securityStateIssueIds.includes('scheme-is-not-cryptographic')) {
      if (securityState === Protocol.Security.SecurityState.Neutral &&
          !securityStateIssueIds.includes('insecure-origin')) {
        summary = ls`This page has a non-HTTPS secure origin.`;
      }
      return {summary, explanations};
    }

    this._explainCertificateSecurity(visibleSecurityState, explanations);
    this._explainConnectionSecurity(visibleSecurityState, explanations);
    this._explainContentSecurity(visibleSecurityState, explanations);
    return {summary, explanations};
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   * @param {string|undefined} summary
   * @param {!Array<!Security.SecurityStyleExplanation>} explanations
   * @returns {string|undefined}
   */
  _explainSafetyTipSecurity(visibleSecurityState, summary, explanations) {
    const {securityStateIssueIds, safetyTipInfo} = visibleSecurityState;
    const currentExplanations = [];

    if (securityStateIssueIds.includes('bad_reputation')) {
      currentExplanations.push({
        summary: ls`This page is suspicious`,
        description: ls
        `Chrome has determined that this site could be fake or fraudulent.\n\nIf you believe this is shown in error please visit https://bugs.chromium.org/p/chromium/issues/entry?template=Safety+Tips+Appeals.`
      });
    } else if (securityStateIssueIds.includes('lookalike') && safetyTipInfo.safeUrl) {
      currentExplanations.push({
        summary: ls`Possible spoofing URL`,
        description: ls`This site's hostname looks similar to ${
            new URL(safetyTipInfo.safeUrl)
                .hostname}. Attackers sometimes mimic sites by making small, hard-to-see changes to the domain name.\n\nIf you believe this is shown in error please visit https://bugs.chromium.org/p/chromium/issues/entry?template=Safety+Tips+Appeals.`
      });
    }

    if (currentExplanations.length > 0) {
      // To avoid overwriting SafeBrowsing's title, set the main summary only if
      // it's empty. The title set here can be overridden by later checks (e.g.
      // bad HTTP).
      summary = summary || ls`This page is suspicious (flagged by Chrome).`;
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Insecure, undefined, currentExplanations[0].summary,
          currentExplanations[0].description));
    }
    return summary;
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   * @param {!Array<!Security.SecurityStyleExplanation>} explanations
   */
  _explainCertificateSecurity(visibleSecurityState, explanations) {
    const {certificateSecurityState, securityStateIssueIds} = visibleSecurityState;
    const title = ls`Certificate`;
    if (certificateSecurityState && certificateSecurityState.certificateHasSha1Signature) {
      const explanationSummary = ls`insecure (SHA-1)`;
      const description = ls`The certificate chain for this site contains a certificate signed using SHA-1.`;
      if (certificateSecurityState.certificateHasWeakSignature) {
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Insecure, title, explanationSummary, description,
            certificateSecurityState.certificate, Protocol.Security.MixedContentType.None));
      } else {
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Neutral, title, explanationSummary, description,
            certificateSecurityState.certificate, Protocol.Security.MixedContentType.None));
      }
    }

    if (certificateSecurityState && securityStateIssueIds.includes('cert-missing-subject-alt-name')) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Insecure, title, ls`Subject Alternative Name missing`,
          ls
          `The certificate for this site does not contain a Subject Alternative Name extension containing a domain name or IP address.`,
          certificateSecurityState.certificate, Protocol.Security.MixedContentType.None));
    }

    if (certificateSecurityState && certificateSecurityState.certificateNetworkError !== null) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Insecure, title, ls`missing`,
          ls`This site is missing a valid, trusted certificate (${certificateSecurityState.certificateNetworkError}).`,
          certificateSecurityState.certificate, Protocol.Security.MixedContentType.None));
    } else if (certificateSecurityState && !certificateSecurityState.certificateHasSha1Signature) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Secure, title, ls`valid and trusted`,
          ls`The connection to this site is using a valid, trusted server certificate issued by ${
              certificateSecurityState.issuer}.`,
          certificateSecurityState.certificate, Protocol.Security.MixedContentType.None));
    }

    if (securityStateIssueIds.includes('pkp-bypassed')) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Info, title, ls`Public-Key-Pinning bypassed`,
          ls`Public-Key-Pinning was bypassed by a local root certificate.`));
    }

    if (certificateSecurityState && certificateSecurityState.isCertificateExpiringSoon()) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Info, undefined, ls`Certificate expires soon`,
          ls`The certificate for this site expires in less than 48 hours and needs to be renewed.`));
    }
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   * @param {!Array<!Security.SecurityStyleExplanation>} explanations
   */
  _explainConnectionSecurity(visibleSecurityState, explanations) {
    const certificateSecurityState = visibleSecurityState.certificateSecurityState;
    if (!certificateSecurityState) {
      return;
    }

    const title = ls`Connection`;
    if (certificateSecurityState.modernSSL) {
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Secure, title, ls`secure connection settings`,
          ls`The connection to this site is encrypted and authenticated using ${certificateSecurityState.protocol}, ${
              certificateSecurityState.getKeyExchangeName()}, and ${certificateSecurityState.getCipherFullName()}.`));
      return;
    }

    const recommendations = [];
    if (certificateSecurityState.obsoleteSslProtocol) {
      recommendations.push(ls`${certificateSecurityState.protocol} is obsolete. Enable TLS 1.2 or later.`);
    }
    if (certificateSecurityState.obsoleteSslKeyExchange) {
      recommendations.push(ls`RSA key exchange is obsolete. Enable an ECDHE-based cipher suite.`);
    }
    if (certificateSecurityState.obsoleteSslCipher) {
      recommendations.push(ls`${certificateSecurityState.cipher} is obsolete. Enable an AES-GCM-based cipher suite.`);
    }
    if (certificateSecurityState.obsoleteSslSignature) {
      recommendations.push(
          ls
          `The server signature uses SHA-1, which is obsolete. Enable a SHA-2 signature algorithm instead. (Note this is different from the signature in the certificate.)`);
    }

    explanations.push(new Security.SecurityStyleExplanation(
        Protocol.Security.SecurityState.Info, title, ls`obsolete connection settings`,
        ls`The connection to this site is encrypted and authenticated using ${certificateSecurityState.protocol}, ${
            certificateSecurityState.getKeyExchangeName()}, and ${certificateSecurityState.getCipherFullName()}.`,
        undefined, undefined, recommendations));
  }

  /**
   * @param {!Security.PageVisibleSecurityState} visibleSecurityState
   * @param {!Array<!Security.SecurityStyleExplanation>} explanations
   */
  _explainContentSecurity(visibleSecurityState, explanations) {
    // Add the secure explanation unless there is an issue.
    let addSecureExplanation = true;
    const title = ls`Resources`;
    const securityStateIssueIds = visibleSecurityState.securityStateIssueIds;

    if (securityStateIssueIds.includes('ran-mixed-content')) {
      addSecureExplanation = false;
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Insecure, title, ls`active mixed content`,
          ls`You have recently allowed non-secure content (such as scripts or iframes) to run on this site.`, [],
          Protocol.Security.MixedContentType.Blockable));
    }

    if (securityStateIssueIds.includes('displayed-mixed-content')) {
      addSecureExplanation = false;
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Neutral, title, ls`mixed content`, ls`This page includes HTTP resources.`, [],
          Protocol.Security.MixedContentType.OptionallyBlockable));
    }

    if (securityStateIssueIds.includes('contained-mixed-form')) {
      addSecureExplanation = false;
      explanations.push(new Security.SecurityStyleExplanation(
          Protocol.Security.SecurityState.Neutral, title, ls`non-secure form`,
          ls`This page includes a form with a non-secure "action" attribute.`));
    }

    if (visibleSecurityState.certificateSecurityState === null ||
        visibleSecurityState.certificateSecurityState.certificateNetworkError === null) {
      if (securityStateIssueIds.includes('ran-content-with-cert-error')) {
        addSecureExplanation = false;
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Insecure, title, ls`active content with certificate errors`,
            ls
            `You have recently allowed content loaded with certificate errors (such as scripts or iframes) to run on this site.`));
      }

      if (securityStateIssueIds.includes('displayed-content-with-cert-errors')) {
        addSecureExplanation = false;
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Neutral, title, ls`content with certificate errors`,
            ls`This page includes resources that were loaded with certificate errors.`));
      }
    }

    if (addSecureExplanation) {
      if (!securityStateIssueIds.includes('scheme-is-not-cryptographic')) {
        explanations.push(new Security.SecurityStyleExplanation(
            Protocol.Security.SecurityState.Secure, title, ls`all served securely`,
            ls`All resources on this page are served securely.`));
      }
    }
  }

  /**
   * @param {!Array<!Security.SecurityStyleExplanation>} explanations
   * @return {!Array<!Security.SecurityStyleExplanation>}
   */
  _orderExplanations(explanations) {
    if (explanations.length === 0) {
      return explanations;
    }
    const securityStateOrder = [
      Protocol.Security.SecurityState.Insecure, Protocol.Security.SecurityState.Neutral,
      Protocol.Security.SecurityState.Secure, Protocol.Security.SecurityState.Info
    ];
    const orderedExplanations = [];
    securityStateOrder.forEach(
        securityState => orderedExplanations.push(
            ...explanations.filter(explanation => explanation.securityState === securityState)));
    return orderedExplanations;
  }

  refreshExplanations() {
    this._securityExplanationsMain.removeChildren();
    this._securityExplanationsExtra.removeChildren();
    for (const explanation of this._explanations) {
      if (explanation.securityState === Protocol.Security.SecurityState.Info) {
        this._addExplanation(this._securityExplanationsExtra, explanation);
      } else {
        switch (explanation.mixedContentType) {
          case Protocol.Security.MixedContentType.Blockable:
            this._addMixedContentExplanation(
                this._securityExplanationsMain, explanation,
                Network.NetworkLogView.MixedContentFilterValues.BlockOverridden);
            break;
          case Protocol.Security.MixedContentType.OptionallyBlockable:
            this._addMixedContentExplanation(
                this._securityExplanationsMain, explanation, Network.NetworkLogView.MixedContentFilterValues.Displayed);
            break;
          default:
            this._addExplanation(this._securityExplanationsMain, explanation);
            break;
        }
      }
    }

    if (this._panel.filterRequestCount(Network.NetworkLogView.MixedContentFilterValues.Blocked) > 0) {
      const explanation = /** @type {!Protocol.Security.SecurityStateExplanation} */ ({
        securityState: Protocol.Security.SecurityState.Info,
        summary: Common.UIString('Blocked mixed content'),
        description: Common.UIString('Your page requested non-secure resources that were blocked.'),
        mixedContentType: Protocol.Security.MixedContentType.Blockable,
        certificate: []
      });
      this._addMixedContentExplanation(
          this._securityExplanationsMain, explanation, Network.NetworkLogView.MixedContentFilterValues.Blocked);
    }
  }

  /**
   * @param {!Element} parent
   * @param {!Protocol.Security.SecurityStateExplanation} explanation
   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
   */
  _addMixedContentExplanation(parent, explanation, filterKey) {
    const element = this._addExplanation(parent, explanation);

    const filterRequestCount = this._panel.filterRequestCount(filterKey);
    if (!filterRequestCount) {
      // Network instrumentation might not have been enabled for the page
      // load, so the security panel does not necessarily know a count of
      // individual mixed requests at this point. Prompt them to refresh
      // instead of pointing them to the Network panel to get prompted
      // to refresh.
      const refreshPrompt = element.createChild('div', 'security-mixed-content');
      refreshPrompt.textContent = Common.UIString('Reload the page to record requests for HTTP resources.');
      return;
    }

    const requestsAnchor = element.createChild('div', 'security-mixed-content devtools-link');
    UI.ARIAUtils.markAsLink(requestsAnchor);
    requestsAnchor.tabIndex = 0;
    if (filterRequestCount === 1) {
      requestsAnchor.textContent = Common.UIString('View %d request in Network Panel', filterRequestCount);
    } else {
      requestsAnchor.textContent = Common.UIString('View %d requests in Network Panel', filterRequestCount);
    }

    requestsAnchor.addEventListener('click', this.showNetworkFilter.bind(this, filterKey));
    requestsAnchor.addEventListener('keydown', event => {
      if (isEnterKey(event)) {
        this.showNetworkFilter(filterKey, event);
      }
    });
  }

  /**
   * @param {!Network.NetworkLogView.MixedContentFilterValues} filterKey
   * @param {!Event} e
   */
  showNetworkFilter(filterKey, e) {
    e.consume();
    Network.NetworkPanel.revealAndFilter(
        [{filterType: Network.NetworkLogView.FilterType.MixedContent, filterValue: filterKey}]);
  }
}

/**
 * @unrestricted
 */
export class SecurityOriginView extends UI.VBox {
  /**
   * @param {!Security.SecurityPanel} panel
   * @param {!Security.SecurityPanel.Origin} origin
   * @param {!Security.SecurityPanel.OriginState} originState
   */
  constructor(panel, origin, originState) {
    super();
    this._panel = panel;
    this.setMinimumSize(200, 100);

    this.element.classList.add('security-origin-view');
    this.registerRequiredCSS('security/originView.css');
    this.registerRequiredCSS('security/lockIcon.css');

    const titleSection = this.element.createChild('div', 'title-section');
    const titleDiv = titleSection.createChild('div', 'title-section-header');
    titleDiv.textContent = ls`Origin`;
    UI.ARIAUtils.markAsHeading(titleDiv, 1);

    const originDisplay = titleSection.createChild('div', 'origin-display');
    this._originLockIcon = originDisplay.createChild('span', 'security-property');
    this._originLockIcon.classList.add('security-property-' + originState.securityState);

    originDisplay.appendChild(Security.SecurityPanel.createHighlightedUrl(origin, originState.securityState));

    const originNetworkDiv = titleSection.createChild('div', 'view-network-button');
    const originNetworkLink = originNetworkDiv.createChild('span', 'devtools-link origin-button');
    originNetworkLink.textContent = ls`View requests in Network Panel`;
    originNetworkLink.addEventListener('click', e => {
      e.consume();
      const parsedURL = new Common.ParsedURL(origin);
      Network.NetworkPanel.revealAndFilter([
        {filterType: Network.NetworkLogView.FilterType.Domain, filterValue: parsedURL.host},
        {filterType: Network.NetworkLogView.FilterType.Scheme, filterValue: parsedURL.scheme}
      ]);
    });
    UI.ARIAUtils.markAsLink(originNetworkLink);

    if (originState.securityDetails) {
      const connectionSection = this.element.createChild('div', 'origin-view-section');
      const connectionDiv = connectionSection.createChild('div', 'origin-view-section-title');
      connectionDiv.textContent = ls`Connection`;
      UI.ARIAUtils.markAsHeading(connectionDiv, 2);

      let table = new Security.SecurityDetailsTable();
      connectionSection.appendChild(table.element());
      table.addRow(Common.UIString('Protocol'), originState.securityDetails.protocol);
      if (originState.securityDetails.keyExchange) {
        table.addRow(Common.UIString('Key exchange'), originState.securityDetails.keyExchange);
      }
      if (originState.securityDetails.keyExchangeGroup) {
        table.addRow(Common.UIString('Key exchange group'), originState.securityDetails.keyExchangeGroup);
      }
      table.addRow(
          Common.UIString('Cipher'),
          originState.securityDetails.cipher +
              (originState.securityDetails.mac ? ' with ' + originState.securityDetails.mac : ''));

      // Create the certificate section outside the callback, so that it appears in the right place.
      const certificateSection = this.element.createChild('div', 'origin-view-section');
      const certificateDiv = certificateSection.createChild('div', 'origin-view-section-title');
      certificateDiv.textContent = ls`Certificate`;
      UI.ARIAUtils.markAsHeading(certificateDiv, 2);

      const sctListLength = originState.securityDetails.signedCertificateTimestampList.length;
      const ctCompliance = originState.securityDetails.certificateTransparencyCompliance;
      let sctSection;
      if (sctListLength || ctCompliance !== Protocol.Network.CertificateTransparencyCompliance.Unknown) {
        // Create the Certificate Transparency section outside the callback, so that it appears in the right place.
        sctSection = this.element.createChild('div', 'origin-view-section');
        const sctDiv = sctSection.createChild('div', 'origin-view-section-title');
        sctDiv.textContent = ls`Certificate Transparency`;
        UI.ARIAUtils.markAsHeading(sctDiv, 2);
      }

      const sanDiv = this._createSanDiv(originState.securityDetails.sanList);
      const validFromString = new Date(1000 * originState.securityDetails.validFrom).toUTCString();
      const validUntilString = new Date(1000 * originState.securityDetails.validTo).toUTCString();

      table = new Security.SecurityDetailsTable();
      certificateSection.appendChild(table.element());
      table.addRow(Common.UIString('Subject'), originState.securityDetails.subjectName);
      table.addRow(Common.UIString('SAN'), sanDiv);
      table.addRow(Common.UIString('Valid from'), validFromString);
      table.addRow(Common.UIString('Valid until'), validUntilString);
      table.addRow(Common.UIString('Issuer'), originState.securityDetails.issuer);

      table.addRow(
          '',
          Security.SecurityPanel.createCertificateViewerButtonForOrigin(
              Common.UIString('Open full certificate details'), origin));

      if (!sctSection) {
        return;
      }

      // Show summary of SCT(s) of Certificate Transparency.
      const sctSummaryTable = new Security.SecurityDetailsTable();
      sctSummaryTable.element().classList.add('sct-summary');
      sctSection.appendChild(sctSummaryTable.element());
      for (let i = 0; i < sctListLength; i++) {
        const sct = originState.securityDetails.signedCertificateTimestampList[i];
        sctSummaryTable.addRow(
            Common.UIString('SCT'), sct.logDescription + ' (' + sct.origin + ', ' + sct.status + ')');
      }

      // Show detailed SCT(s) of Certificate Transparency.
      const sctTableWrapper = sctSection.createChild('div', 'sct-details');
      sctTableWrapper.classList.add('hidden');
      for (let i = 0; i < sctListLength; i++) {
        const sctTable = new Security.SecurityDetailsTable();
        sctTableWrapper.appendChild(sctTable.element());
        const sct = originState.securityDetails.signedCertificateTimestampList[i];
        sctTable.addRow(Common.UIString('Log name'), sct.logDescription);
        sctTable.addRow(Common.UIString('Log ID'), sct.logId.replace(/(.{2})/g, '$1 '));
        sctTable.addRow(Common.UIString('Validation status'), sct.status);
        sctTable.addRow(Common.UIString('Source'), sct.origin);
        sctTable.addRow(Common.UIString('Issued at'), new Date(sct.timestamp).toUTCString());
        sctTable.addRow(Common.UIString('Hash algorithm'), sct.hashAlgorithm);
        sctTable.addRow(Common.UIString('Signature algorithm'), sct.signatureAlgorithm);
        sctTable.addRow(Common.UIString('Signature data'), sct.signatureData.replace(/(.{2})/g, '$1 '));
      }

      // Add link to toggle between displaying of the summary of the SCT(s) and the detailed SCT(s).
      if (sctListLength) {
        function toggleSctDetailsDisplay() {
          let buttonText;
          const isDetailsShown = !sctTableWrapper.classList.contains('hidden');
          if (isDetailsShown) {
            buttonText = ls`Show full details`;
          } else {
            buttonText = ls`Hide full details`;
          }
          toggleSctsDetailsLink.textContent = buttonText;
          UI.ARIAUtils.setAccessibleName(toggleSctsDetailsLink, buttonText);
          UI.ARIAUtils.setExpanded(toggleSctsDetailsLink, !isDetailsShown);
          sctSummaryTable.element().classList.toggle('hidden');
          sctTableWrapper.classList.toggle('hidden');
        }
        const toggleSctsDetailsLink =
            UI.createTextButton(ls`Show full details`, toggleSctDetailsDisplay, 'details-toggle');
        sctSection.appendChild(toggleSctsDetailsLink);
      }

      switch (ctCompliance) {
        case Protocol.Network.CertificateTransparencyCompliance.Compliant:
          sctSection.createChild('div', 'origin-view-section-notes').textContent =
              Common.UIString('This request complies with Chrome\'s Certificate Transparency policy.');
          break;
        case Protocol.Network.CertificateTransparencyCompliance.NotCompliant:
          sctSection.createChild('div', 'origin-view-section-notes').textContent =
              Common.UIString('This request does not comply with Chrome\'s Certificate Transparency policy.');
          break;
        case Protocol.Network.CertificateTransparencyCompliance.Unknown:
          break;
      }

      const noteSection = this.element.createChild('div', 'origin-view-section origin-view-notes');
      if (originState.loadedFromCache) {
        noteSection.createChild('div').textContent =
            Common.UIString('This response was loaded from cache. Some security details might be missing.');
      }
      noteSection.createChild('div').textContent =
          Common.UIString('The security details above are from the first inspected response.');
    } else if (originState.securityState === Protocol.Security.SecurityState.Secure) {
      // If the security state is secure but there are no security details,
      // this means that the origin is a non-cryptographic secure origin, e.g.
      // chrome:// or about:.
      const secureSection = this.element.createChild('div', 'origin-view-section');
      const secureDiv = secureSection.createChild('div', 'origin-view-section-title');
      secureDiv.textContent = ls`Secure`;
      UI.ARIAUtils.markAsHeading(secureDiv, 2);
      secureSection.createChild('div').textContent = ls`This origin is a non-HTTPS secure origin.`;
    } else if (originState.securityState !== Protocol.Security.SecurityState.Unknown) {
      const notSecureSection = this.element.createChild('div', 'origin-view-section');
      const notSecureDiv = notSecureSection.createChild('div', 'origin-view-section-title');
      notSecureDiv.textContent = ls`Not secure`;
      UI.ARIAUtils.markAsHeading(notSecureDiv, 2);
      notSecureSection.createChild('div').textContent =
          Common.UIString('Your connection to this origin is not secure.');
    } else {
      const noInfoSection = this.element.createChild('div', 'origin-view-section');
      const noInfoDiv = noInfoSection.createChild('div', 'origin-view-section-title');
      noInfoDiv.textContent = ls`No security information`;
      UI.ARIAUtils.markAsHeading(noInfoDiv, 2);
      noInfoSection.createChild('div').textContent =
          Common.UIString('No security details are available for this origin.');
    }
  }

  /**
   * @param {!Array<string>} sanList
   * @return {!Element}
   */
  _createSanDiv(sanList) {
    const sanDiv = createElement('div');
    if (sanList.length === 0) {
      sanDiv.textContent = Common.UIString('(n/a)');
      sanDiv.classList.add('empty-san');
    } else {
      const truncatedNumToShow = 2;
      const listIsTruncated = sanList.length > truncatedNumToShow + 1;
      for (let i = 0; i < sanList.length; i++) {
        const span = sanDiv.createChild('span', 'san-entry');
        span.textContent = sanList[i];
        if (listIsTruncated && i >= truncatedNumToShow) {
          span.classList.add('truncated-entry');
        }
      }
      if (listIsTruncated) {
        function toggleSANTruncation() {
          const isTruncated = sanDiv.classList.contains('truncated-san');
          let buttonText;
          if (isTruncated) {
            sanDiv.classList.remove('truncated-san');
            buttonText = ls`Show less`;
          } else {
            sanDiv.classList.add('truncated-san');
            buttonText = ls`Show more (${sanList.length} total)`;
          }
          truncatedSANToggle.textContent = buttonText;
          UI.ARIAUtils.setAccessibleName(truncatedSANToggle, buttonText);
          UI.ARIAUtils.setExpanded(truncatedSANToggle, isTruncated);
        }
        const truncatedSANToggle = UI.createTextButton(ls`Show more (${sanList.length} total)`, toggleSANTruncation);
        sanDiv.appendChild(truncatedSANToggle);
        toggleSANTruncation();
      }
    }
    return sanDiv;
  }

  /**
   * @param {!Protocol.Security.SecurityState} newSecurityState
   */
  setSecurityState(newSecurityState) {
    for (const className of Array.prototype.slice.call(this._originLockIcon.classList)) {
      if (className.startsWith('security-property-')) {
        this._originLockIcon.classList.remove(className);
      }
    }

    this._originLockIcon.classList.add('security-property-' + newSecurityState);
  }
}

/**
 * @unrestricted
 */
export class SecurityDetailsTable {
  constructor() {
    this._element = createElement('table');
    this._element.classList.add('details-table');
  }

  /**
   * @return: {!Element}
   */
  element() {
    return this._element;
  }

  /**
   * @param {string} key
   * @param {string|!Node} value
   */
  addRow(key, value) {
    const row = this._element.createChild('div', 'details-table-row');
    row.createChild('div').textContent = key;

    const valueDiv = row.createChild('div');
    if (typeof value === 'string') {
      valueDiv.textContent = value;
    } else {
      valueDiv.appendChild(value);
    }
  }
}

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

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

/**
 * @constructor
 */
Security.SecurityPanel = SecurityPanel;

/** @typedef {string} */
Security.SecurityPanel.Origin;

/**
 * @typedef {Object}
 * @property {!Protocol.Security.SecurityState} securityState
 * @property {?Protocol.Network.SecurityDetails} securityDetails
 * @property {?bool} loadedFromCache
 * @property {?Security.SecurityOriginView} originView
 */
Security.SecurityPanel.OriginState;

/**
 * @constructor
 */
Security.SecurityPanelSidebarTree = SecurityPanelSidebarTree;

/** @enum {symbol} */
Security.SecurityPanelSidebarTree.OriginGroup = OriginGroup;

/**
 * @constructor
 */
Security.SecurityPanelSidebarTreeElement = SecurityPanelSidebarTreeElement;

/**
 * @constructor
 */
Security.SecurityMainView = SecurityMainView;

/**
 * @constructor
 */
Security.SecurityOriginView = SecurityOriginView;

/**
 * @constructor
 */
Security.SecurityDetailsTable = SecurityDetailsTable;
