// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {assert} from 'chrome://resources/js/assert.js';
import {CustomElement} from 'chrome://resources/js/custom_element.js';

import type {AngleFeature, BrowserBridge, ClientInfo, FeatureStatus, Problem} from './browser_bridge.js';
import {getTemplate} from './info_view.html.js';
import {VulkanInfo} from './vulkan_info.js';

/**
 * Given a blob and a filename, prompts user to
 * save as a file.
 */
const saveData = (function() {
  const a = document.createElement('a');
  a.style.display = 'none';
  document.body.appendChild(a);
  return function saveData(blob: Blob, fileName: string) {
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = fileName;
    a.click();
  };
}());

function getProblemTextAndUrl(problem: Problem) {
  let text = problem.description;
  let url = '';
  const pattern = ' Please update your graphics driver via this link: ';
  const pos = text.search(pattern);
  if (pos > 0) {
    url = text.substring(pos + pattern.length);
    text = text.substring(0, pos);
  }
  return {text, url};
}

/**
 * Calls a function to insert an element between every element
 * of an existing array
 */
function insertBetweenElements<Type>(
    array: Type[], fn: (i: number) => Type): Type[] {
  const newArray = array.slice(0, 1);
  for (let i = 1; i < array.length; ++i) {
    newArray.push(fn(i), array[i] as Type);
  }
  return newArray;
}

/** Inserts <span>, </span> between every element in array */
function separateByCommas(array: HTMLElement[], comma = ', ') {
  return insertBetweenElements(array, () => createElem('span', comma));
}

/**
 * Conditionally add elements to an array
 *
 * ```js
 * const array = [
 *   "carrots",
 *   "potatoes",
 *   ...addIf(haveFruit, () => ["apple", "cherry"]),
 * ]
 * ```
 *
 * The function is not called if `cond` is false.
 */
function addIf<T>(cond: boolean, fn: () => T[]) {
  return cond ? fn() : [];
}

/**
 * Word wraps a string, prefixing each line.
 */
function wordWrap(s: string, prefix = '    ', maxLength?: number) {
  maxLength = maxLength || (80 - prefix.length);
  const lines: string[] = [];
  const words = s.split(' ');
  const line: string[] = [];
  let length = 0;
  for (const word of words) {
    if (length + word.length + 1 >= maxLength) {
      lines.push(line.join(' '));
      line.length = 0;
      length = 0;
    }
    line.push(word);
    length += word.length + 1;
  }
  if (line.length) {
    lines.push(line.join(' '));
  }
  return lines.map(s => `${prefix}${s}`).join('\n');
}

interface Attributes {
  [key: string]: string|Attributes;
}

/**
 * Creates an HTMLElement with optional attributes and children
 *
 * Examples:
 *
 * ```js
 *   br = createElem('br');
 *   p = createElem('p', 'hello world');
 *   a = createElem('a', {href: 'https://google.com', textContent: 'Google'});
 *   ul = createElement('ul', {}, [
 *     createElem('li', 'apple'),
 *     createElem('li', 'banana'),
 *   ]);
 *   h1 = createElem('h1', { style: { color: 'red' }, textContent: 'Title'})
 * ```
 */
function createElem(
    tag: string, attrs: Attributes|string = {}, children: HTMLElement[] = []) {
  const elem = document.createElement(tag) as HTMLElement;
  if (typeof attrs === 'string') {
    elem.textContent = attrs;
  } else {
    const elemAsAttribs = elem as unknown as Attributes;
    for (const [key, value] of Object.entries(attrs)) {
      if (typeof value === 'function' && key.startsWith('on')) {
        const eventName = key.substring(2).toLowerCase();
        elem.addEventListener(eventName, value, {passive: false});
      } else if (typeof value === 'object') {
        for (const [k, v] of Object.entries(value)) {
          (elemAsAttribs[key] as Attributes)[k] = v;
        }
      } else if (elemAsAttribs[key] === undefined) {
        elem.setAttribute(key, value);
      } else {
        elemAsAttribs[key] = value;
      }
    }
  }
  for (const child of children) {
    elem.appendChild(child);
  }
  return elem;
}

export interface Data {
  description: string;
  id?: string;
  value: string;
}

export interface ArrayData {
  description: string;
  value: Data[];
}

/** Creates the td elements for a table row */
function createInfoElements(
    data: Data|ArrayData, padSize: number): HTMLElement[] {
  const desc = createElem('td', {}, [
    createElem('span', data.description.padEnd(padSize)),
    createHidden(':'),
  ]);

  if (Array.isArray(data.value)) {
    return [
      desc,
      createElem('td', {}, [createInfoTable((data as ArrayData).value)]),
    ];
  } else {
    return [
      desc,
      createElem('td', {
        textContent: data.value.toString().trim(),
        id: (data as Data).id!,
      }),
    ];
  }
}

/** Creates a table from the given data */
function createInfoTable(data: Data[]|ArrayData[]) {
  const longestDesc = Math.min(
      32,
      (data as Data[])
          .reduce(
              (longest, {description}) => Math.max(longest, description.length),
              0));
  return createElem('table', {className: 'info-table'}, [
    createElem(
        'tbody', {},
        data.map(
            data => createElem('tr', {}, createInfoElements(data, longestDesc)),
            )),
  ]);
}

/**
 * Creates a hidden span that will only be used when the when
 * the user copies or downloads text.
 */
function createHidden(textContent: string) {
  return createElem('span', {className: 'copy', textContent});
}

/**
 * Given a string or Attributes returns the `textContent`
 * and the attributes with `textContent` removed
 */
function separateTextContentFromAttributes(attrs: Attributes|string = {}) {
  return typeof attrs === 'string' ? {textContent: attrs, attribs: {}} : {
    textContent: attrs['textContent'] as string || '',
    attribs: {...attrs, textContent: ''},
  };
}

/**
 * Creates a list item with a hidden `*   ` span prepended for copy
 */
function createLi(attrs: Attributes|string = {}, children: HTMLElement[] = []) {
  const {textContent, attribs} = separateTextContentFromAttributes(attrs);
  return createElem('li', attribs, [
    createHidden('*   '),
    createElem('span', textContent),
    ...children,
  ]);
}

/**
 * Creates a heading tag with hidden text for copying
 * so the copy will be like markdown.
 */
function createHeading(
    tag: string, padChar: string, attrs: Attributes|string = {},
    children: HTMLElement[] = []) {
  const {textContent, attribs} = separateTextContentFromAttributes(attrs);
  return createElem(tag, attribs, [
    createHidden('\n\n'),
    createElem('span', textContent),
    createHidden(`\n${''.padEnd(textContent.length, padChar)}`),
    ...children,
  ]);
}

/**
 * Creates a link pair with an anchor tag that is visible
 * in the page and hidden text for copying so the copy
 * will appear as (href)
 */
function createLinkPair(textContent: string, href: string) {
  return [
    createElem('a', {
      className: 'hide-on-copy',
      textContent,
      href,
    }),
    createHidden(`(${href})`),
  ];
}

/**
 * Get a string data value
 */
function getDataValue(data: Data|ArrayData): string {
  return Array.isArray(data.value) ?
      data.value.map(data => getDataValue(data)).join(',') :
      data.value;
}

/**
 * Go through Datas and find ones that start with 'GPUx'
 * return the first with who's value ends itn '*ACTIVE*'
 * or else the first one.
 * @param data
 * @returns
 */
function getActiveGPU(data: Data[]|ArrayData[]) {
  // get list of GPUs
  const gpus =
      [...data].filter(({description}) => /^GPU\d+$/.test(description));
  // get list of active GPUs
  const active = gpus.filter(data => getDataValue(data).endsWith('*ACTIVE*'));
  const all = [...active, ...gpus];
  // get the first one
  if (all.length > 0) {
    const gpu = getDataValue(all[0]!);
    const parts = gpu.split(', ')[0]!.split('=');
    return parts.length === 2 && parts[0]! === 'VENDOR' ? parseInt(parts[1]!) :
                                                          0;
  }
  return 0;
}

/** convert a value to a string or empty string if null or undefined */
function safeString(value: any) {
  return typeof value === 'undefined' || value === null ? '' : value.toString();
}

const kSections = {
  featureStatus: ['Graphics Feature Status', 'ul'],
  clientInfo: ['Version Information', 'div'],
  basicInfo: ['Driver Information', 'div'],
  workarounds: ['Driver Bug Workarounds', 'ul'],
  problems: ['Problems Detected', 'ul'],
  angleFeatures: ['ANGLE Features', 'ul'],
  dawnInfo: ['Dawn Info', 'ul'],
  compositorInfo: ['Compositor Information', 'div'],
  gpuMemoryBufferInfo: ['GpuMemoryBuffers Status', 'div'],
  displayInfo: ['Display(s) Information', 'div'],
  videoAccelerationInfo: ['Video Acceleration Information', 'div'],
  vulkanInfo: ['Vulkan Information', 'div'],
  devicePerfInfo: ['Device Performance Information', 'div'],
  diagnostics: ['Diagnostics', 'div'],
  basicInfoForHardwareGpu: ['Driver Information for Hardware GPU', 'div'],
  featureStatusForHardwareGpu:
      ['Graphics Feature Status for Hardware GPU', 'ul'],
  workaroundsForHardwareGpu: ['Driver Bug Workarounds for Hardware GPU', 'ul'],
  problemsForHardwareGpu: ['Problems Detected for Hardware GPU', 'ul'],
  logMessages: ['Log Messages', 'ul'],
} as const;

interface Section {
  div: HTMLElement;
  list: HTMLElement;
  wrap: HTMLElement;
}

type Sections = {
  [key in keyof typeof kSections]: Section
};

/**
 * @fileoverview This view displays information on the current GPU
 * hardware.  Its primary usefulness is to allow users to copy-paste
 * their data in an easy to read format for bug reports.
 */
export class InfoViewElement extends CustomElement {
  browserBridge?: BrowserBridge;
  sections?: Sections;

  static override get template() {
    return getTemplate();
  }

  addBrowserBridgeListeners(browserBridge: BrowserBridge) {
    browserBridge.addEventListener(
        'gpuInfoUpdate', this.refresh.bind(this, browserBridge));
    browserBridge.addEventListener(
        'logMessagesChange', this.refresh.bind(this, browserBridge));
    browserBridge.addEventListener(
        'clientInfoChange', this.refresh.bind(this, browserBridge));
    this.refresh(browserBridge);
  }

  /**
   * public interface for testing
   */
  getInfo(category: string, feature: string = ''): string|string[] {
    const gpuInfo = this.browserBridge?.gpuInfo;
    if (!gpuInfo) {
      throw new Error('no gpuInfo');
    }

    switch (category) {
      case 'feature-status-for-hardware-gpu-list':
        return safeString(
            gpuInfo.featureStatusForHardwareGpu?.featureStatus[feature]);
      case 'feature-status-list':
        return safeString(gpuInfo.featureStatus?.featureStatus[feature]);
      case 'active-gpu-for-hardware':
        return safeString(getActiveGPU(gpuInfo.basicInfoForHardwareGpu));
      case 'active-gpu':
        return safeString(getActiveGPU(gpuInfo.basicInfo));
      case 'workarounds':
        return (gpuInfo.featureStatus || gpuInfo.featureStatusForHardwareGpu)
                   ?.workarounds ||
            [];
      default:
        throw new Error(`unknown category: ${category}`);
    }
  }

  getSelectionText(all: boolean) {
    const dynamicStyle = this.getRequiredElement('#dynamic-style')!;
    dynamicStyle.textContent = `
      #content { white-space: pre !important; }
      .copy { display: initial; }
      .hide-on-copy { display: none; }
    `;
    const contentDiv = this.getRequiredElement('#content')!;

    // document.getSelection doesn't work through shadowDom
    // and shadowRoot getSelection is non-standard chromium
    const shadowDoc = this.shadowRoot! as unknown as Document;
    const selection = shadowDoc.getSelection()!;

    if (all) {
      selection.removeAllRanges();
      selection.selectAllChildren(contentDiv);
    } else {
      const position =
          selection.anchorNode?.compareDocumentPosition(selection.focusNode!);
      const [startNode, startOffset, endNode, endOffset] =
          ((position || 0) & Node.DOCUMENT_POSITION_FOLLOWING) ?
          [
            selection.anchorNode!,
            selection.anchorOffset,
            selection.focusNode!,
            selection.focusOffset,
          ] :
          [
            selection.focusNode!,
            selection.focusOffset,
            selection.anchorNode!,
            selection.anchorOffset,
          ];
      if (startOffset === 0) {
        // Given the selection between > and <
        //
        //   * >abc
        //   * def<
        //
        // We need to move the start of the selection back to the parent
        // otherwise the selection above will copied as
        //
        //   abc
        //   * def
        //
        // since the * (the list item's bullet) is not selectable directly.
        const li = startNode.parentElement?.closest('li');
        selection.setBaseAndExtent(
            li || startNode.parentNode!, 0, endNode, endOffset);
      }
    }

    // Get text and remove superfluous lines and whitespace.
    const text = selection.toString()
                     .replace(/\s*\n\s*\n\s*\n+/g, '\n\n')
                     .replace(/\t/g, ' ')
                     .trim();

    if (all) {
      shadowDoc.getSelection()?.removeAllRanges();
    }

    dynamicStyle.textContent = '';
    return text;
  }


  connectedCallback() {
    // Add handler to 'download report to clipboard' button
    const downloadButton = this.getRequiredElement('#download-to-file');
    assert(downloadButton);
    downloadButton.onclick = (() => {
      const text = this.getSelectionText(true);
      const blob = new Blob([text], {type: 'text/text'});
      const filename = `about-gpu-${
          new Date().toISOString().replace(/[^a-z0-9-]/ig, '-')}.txt`;
      saveData(blob, filename);
    });

    // Add a copy handler to massage the text for plain text.
    document.addEventListener('copy', (event) => {
      const text = this.getSelectionText(false);
      event!.clipboardData!.setData('text/plain', text);
      event.preventDefault();
    });

    const contentDiv = this.getRequiredElement('#content')!;
    this.sections = Object.fromEntries(Object.entries(kSections).map(
                        ([propName, [title, tag]]) => {
                          const div = createHeading('h3', '=', title);
                          const list = createElem(tag);
                          const wrap = createElem('div', {}, [
                            div,
                            list,
                          ]);
                          contentDiv.appendChild(wrap);
                          return [propName, {div, list, wrap}];
                        })) as Sections;
  }

  /**
   * Updates the view based on its currently known data
   */
  refresh(browserBridge: BrowserBridge) {
    this.browserBridge = browserBridge;
    let clientInfo: ClientInfo;
    function createSourcePermalink(
        revisionIdentifier: string, filepath: string): string {
      if (revisionIdentifier.length !== 40) {
        // If the revision id isn't a hash, just use the 0.0.0.0 version
        // from the Chrome version string "Chrome/0.0.0.0".
        revisionIdentifier = clientInfo.version.split('/')[1]!;
      }
      return `https://chromium.googlesource.com/chromium/src/+/${
          revisionIdentifier}/${filepath}`;
    }

    const sections = this.sections!;

    // Client info
    if (browserBridge.clientInfo) {
      clientInfo = browserBridge.clientInfo;

      this.setTable_(sections.clientInfo, [
        {description: 'Data exported', value: (new Date()).toISOString()},
        {description: 'Chrome version', value: clientInfo.version},
        {description: 'Operating system', value: clientInfo.operating_system},
        {
          description: 'Software rendering list URL',
          value: createSourcePermalink(
              clientInfo.revision_identifier,
              'gpu/config/software_rendering_list.json'),
        },
        {
          description: 'Driver bug list URL',
          value: createSourcePermalink(
              clientInfo.revision_identifier,
              'gpu/config/gpu_driver_bug_list.json'),
        },
        {description: 'ANGLE commit id', value: clientInfo.angle_commit_id},
        {
          description: '2D graphics backend',
          value: clientInfo.graphics_backend,
        },
        {description: 'Command Line', value: clientInfo.command_line},
      ]);
    } else {
      sections.clientInfo.list.textContent = '... loading ...';
    }

    const gpuInfo = browserBridge.gpuInfo;
    if (gpuInfo) {
      // Not using jstemplate here for blocklist status because we construct
      // href from data, which jstemplate can't seem to do.
      if (gpuInfo.featureStatus) {
        this.appendFeatureInfo_(
            gpuInfo.featureStatus, sections.featureStatus.list,
            sections.problems, sections.workarounds);
      } else {
        sections.featureStatus.list.textContent = '';
        sections.problems.list.hidden = true;
        sections.workarounds.list.hidden = true;
      }

      const hideHardware = !gpuInfo.featureStatusForHardwareGpu;
      sections.basicInfoForHardwareGpu.div.hidden = hideHardware;
      sections.featureStatusForHardwareGpu.div.hidden = hideHardware;
      sections.problemsForHardwareGpu.div.hidden = hideHardware;
      sections.workaroundsForHardwareGpu.div.hidden = hideHardware;
      if (!hideHardware) {
        this.appendFeatureInfo_(
            gpuInfo.featureStatusForHardwareGpu,
            sections.featureStatusForHardwareGpu.list,
            sections.problemsForHardwareGpu,
            sections.workaroundsForHardwareGpu);
        this.setTable_(
            sections.basicInfoForHardwareGpu, gpuInfo.basicInfoForHardwareGpu);
      }

      this.setTable_(sections.basicInfo, gpuInfo.basicInfo);
      this.setTable_(sections.compositorInfo, gpuInfo.compositorInfo);
      this.setTable_(sections.gpuMemoryBufferInfo, gpuInfo.gpuMemoryBufferInfo);
      this.setTable_(sections.displayInfo, gpuInfo.displayInfo);
      this.setTable_(
          sections.videoAccelerationInfo, gpuInfo.videoAcceleratorsInfo);

      this.updateSectionList_(
          sections.angleFeatures, gpuInfo.ANGLEFeatures,
          angleFeature => this.createAngleFeatureEl_(angleFeature));

      this.updateSection_(sections.dawnInfo, () => {
        const show = !!gpuInfo.dawnInfo && gpuInfo.dawnInfo.length > 0;
        if (show) {
          this.createDawnInfoEl_(sections.dawnInfo.list, gpuInfo.dawnInfo!);
        }
        return show;
      });

      this.updateSectionTable_(sections.diagnostics, gpuInfo.diagnostics);

      this.setTable_(
          sections.vulkanInfo,
          gpuInfo.vulkanInfo ? [{
            'description': 'info',
            'value': new VulkanInfo(gpuInfo.vulkanInfo).toString(),
            'id': 'vulkan-info-value',
          }] :
                               []);

      this.setTable_(sections.devicePerfInfo, gpuInfo.devicePerfInfo);
    } else {
      sections.basicInfo.list.textContent = '... loading ...';
      sections.diagnostics.div.hidden = true;
      sections.featureStatus.list.textContent = '';
      sections.problems.div.hidden = true;
      sections.dawnInfo.div.hidden = true;
    }

    // Log messages
    sections.logMessages.list.textContent = '';
    browserBridge.logMessages.forEach(messageObj => {
      sections.logMessages.list.appendChild(
          createElem('li', `${messageObj.header}: ${messageObj.message}`));
    });
  }

  /**
   * Clears a section and then updates it by calling fn. If fn returns false
   * it hides the section.
   */
  private updateSection_(section: Section, fn: () => boolean) {
    section.list.textContent = '';
    const show = fn();
    section.div.hidden = !show;
  }

  /**
   * Clears and and updates a section from a list. If the list is empty it
   * hides the section
   */
  private updateSectionList_<T>(
      section: Section, list: T[]|undefined, fn: (item: T) => HTMLElement) {
    this.updateSection_(section, () => {
      if (list) {
        for (const item of list) {
          section.list.appendChild(fn(item));
        }
      }
      return !!list && list.length > 0;
    });
  }

  /** Update a table, hiding it of the table has no elements */
  private updateSectionTable_(
      section: Section, inputData: Data[]|ArrayData[]|undefined) {
    this.updateSection_(section, () => {
      this.setTable_(section, inputData);
      return !!inputData && inputData.length > 0;
    });
  }

  private appendFeatureInfo_(
      featureInfo: FeatureStatus, featureStatusList: HTMLElement,
      problems: Section, workarounds: Section) {
    // Feature map
    const featureLabelMap: Record<string, string> = {
      '2d_canvas': 'Canvas',
      'gpu_compositing': 'Compositing',
      'webgl': 'WebGL',
      'multisampling': 'WebGL multisampling',
      'texture_sharing': 'Texture Sharing',
      'video_decode': 'Video Decode',
      'rasterization': 'Rasterization',
      'opengl': 'OpenGL',
      'metal': 'Metal',
      'vulkan': 'Vulkan',
      'multiple_raster_threads': 'Multiple Raster Threads',
      'native_gpu_memory_buffers': 'Native GpuMemoryBuffers',
      'protected_video_decode': 'Hardware Protected Video Decode',
      'surface_control': 'Surface Control',
      'vpx_decode': 'VPx Video Decode',
      'webgl2': 'WebGL2',
      'canvas_oop_rasterization': 'Canvas out-of-process rasterization',
      'raw_draw': 'Raw Draw',
      'video_encode': 'Video Encode',
      'direct_rendering_display_compositor':
          'Direct Rendering Display Compositor',
      'webgpu': 'WebGPU',
      'skia_graphite': 'Skia Graphite',
      'webnn': 'WebNN',
    };

    const statusMap: Record<string, {label: string, class: string}> = {
      'disabled_software': {
        'label': 'Software only. Hardware acceleration disabled',
        'class': 'feature-yellow',
      },
      'disabled_off': {'label': 'Disabled', 'class': 'feature-red'},
      'disabled_off_ok': {'label': 'Disabled', 'class': 'feature-yellow'},
      'unavailable_software': {
        'label': 'Software only, hardware acceleration unavailable',
        'class': 'feature-yellow',
      },
      'unavailable_off': {'label': 'Unavailable', 'class': 'feature-red'},
      'unavailable_off_ok': {
        'label': 'Unavailable',
        'class': 'feature-yellow',
      },
      'enabled_readback': {
        'label': 'Hardware accelerated but at reduced performance',
        'class': 'feature-yellow',
      },
      'enabled_force': {
        'label': 'Hardware accelerated on all pages',
        'class': 'feature-green',
      },
      'enabled': {'label': 'Hardware accelerated', 'class': 'feature-green'},
      'enabled_on': {'label': 'Enabled', 'class': 'feature-green'},
      'enabled_force_on': {'label': 'Force enabled', 'class': 'feature-green'},
    };

    // feature status list
    featureStatusList.textContent = '';
    for (const featureName in featureInfo.featureStatus) {
      const featureStatus = featureInfo.featureStatus[featureName]!;

      const label = featureLabelMap[featureName];
      if (!label) {
        console.info('Missing featureLabel for', featureName);
      }

      const statusInfo = statusMap[featureStatus];
      if (!statusInfo) {
        console.info('Missing status for ', featureStatus);
      }

      featureStatusList.appendChild(createLi({}, [
        createElem('span', `${label}: `),

        createElem(
            'span',
            statusInfo ? {
              textContent: statusInfo['label'],
              className: statusInfo['class'],
            } :
                         {
                           textContent: 'Unknown',
                           className: 'feature-red',
                         },
            ),
      ]));
    }

    // problems list
    this.updateSectionList_(
        problems, featureInfo.problems,
        problem => this.createProblemEl_(problem));

    // driver bug workarounds list
    this.updateSectionList_(
        workarounds, featureInfo.workarounds,
        workaround => createLi(workaround));
  }

  private createProblemEl_(problem: Problem): HTMLElement {
    const {text, url} = getProblemTextAndUrl(problem);
    return createLi({}, [
      createElem('span', text),

      // add bug separator
      ...addIf(
          problem.crBugs.length > 0, () => [createElem('span', ':\n    ')]),

      // add bugs
      ...separateByCommas(problem.crBugs.map((id) => {
        const bugId = parseInt(id);
        const href = `http://crbug.com/${bugId}`;
        return createElem('span', {}, createLinkPair(bugId.toString(), href));
      })),

      // add affectedGpuSettings
      ...addIf(
          problem.affectedGpuSettings.length > 0,
          () =>
              [createElem('br'),
               createHidden('    '),
               createElem(
                   'i', {},
                   [
                     createElem(
                         'span',
                         problem.tag === 'disabledFeatures' ?
                             'Disabled Features: ' :
                             'Applied Workarounds: '),
                     ...separateByCommas(
                         problem.affectedGpuSettings.map(
                             (textContent) => createElem('span', {
                               textContent,
                               className: problem.tag === 'disabledFeatures' ?
                                   'feature-red' :
                                   'feature-yellow',
                             }),
                             ),
                         ',\n        '),
                   ]),
    ]),

      // add driver update link
      ...addIf(
          !!url,
          () =>
              [createElem('br'),
               createHidden('    '),
               createElem(
                   'b', {className: 'bg-yellow'},
                   [
                     createElem(
                         'span', 'Please update your graphics drive via '),
                     createElem('a', {textContent: 'this link', href: url}),
                   ]),
    ]),

      // for copy spacing
      createElem('span', '\n\n'),

    ]);
  }

  private createAngleFeatureEl_(angleFeature: AngleFeature) {
    return createLi({}, [
      // Name comes first, bolded
      createElem('b', angleFeature.name),

      // If there's a category, it follows the name in parentheses
      ...addIf(
          !!angleFeature.category,
          () =>
              [createElem('span', ` (${angleFeature.category})`),
    ]),

      // Follow with a colon, and the status (colored)
      createElem('span', ': '),
      createElem(
          'span',
          angleFeature.status === 'enabled' ?
              {className: 'feature-green', textContent: 'Enabled'} :
              {className: 'feature-red', textContent: 'Disabled'}),

      // for copy spacing
      createElem('span', '\n\n'),
    ]);
  }

  private setTable_(section: Section, inputData: Data[]|ArrayData[]|undefined) {
    section.list.textContent = '';
    section.list.appendChild(createInfoTable(inputData || []));
  }

  private createDawnInfoEl_(dawnInfoList: HTMLElement, gpuDawnInfo: string[]) {
    dawnInfoList.textContent = '';
    let inProcessingToggles = false;

    for (let i = 0; i < gpuDawnInfo.length; ++i) {
      const infoString = gpuDawnInfo[i]!;
      let infoEl: HTMLElement;

      if (infoString.startsWith('<')) {
        // GPU type and backend type.
        // Add an empty line for the next adaptor.
        dawnInfoList.appendChild(createElem('br'));

        // e.g. <Discrete GPU> D3D12 backend
        infoEl = createHeading('h3', '-', infoString);
        inProcessingToggles = false;
      } else if (infoString.startsWith('[')) {
        // e.g. [Enabled Toggle Names]
        infoEl = createHeading('h4', '-', {
          className: 'dawn-info-header',
          textContent: infoString,
        });

        if (infoString === '[WebGPU Status]' ||
            infoString === '[Adapter Supported Features]') {
          inProcessingToggles = false;
        } else {
          inProcessingToggles = true;
        }
      } else if (inProcessingToggles) {
        // Each toggle takes 3 strings
        infoEl = createLi({}, [
          // The toggle name comes first, bolded.
          createElem('b', `${infoString}: \n    `),

          // URL
          ...createLinkPair(gpuDawnInfo[++i]!, gpuDawnInfo[i]!),

          // Description, italicized
          createElem('i', `:\n${wordWrap(gpuDawnInfo[++i]!)}`),

          // for copy spacing
          createElem('span', '\n\n'),
        ]);
      } else {
        // Display supported extensions
        infoEl = createLi(infoString);
      }

      dawnInfoList.appendChild(infoEl);
    }
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'info-view': InfoViewElement;
  }
}

customElements.define('info-view', InfoViewElement);
