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

import 'chrome://resources/cr_elements/cr_tree/cr_tree.js';

import type {CrTreeElement} from 'chrome://resources/cr_elements/cr_tree/cr_tree.js';
import type {CrTreeItemElement} from 'chrome://resources/cr_elements/cr_tree/cr_tree_item.js';
import {MAY_HAVE_CHILDREN_ATTR} from 'chrome://resources/cr_elements/cr_tree/cr_tree_item.js';
import {assert} from 'chrome://resources/js/assert.js';

import type {FrameInfo, ProcessInternalsHandlerRemote, WebContentsInfo} from './process_internals.mojom-webui.js';
import {FrameInfo_Type, ProcessInternalsHandler} from './process_internals.mojom-webui.js';

/**
 * Reference to the backend providing all the data.
 */
let pageHandler: ProcessInternalsHandlerRemote|null = null;

/**
 * @return True if successful.
 */
function selectTab(id: string): boolean {
  const tabContents = document.querySelectorAll<HTMLElement>('#content > div');
  const navigation = document.querySelector<HTMLElement>('#navigation');
  assert(navigation);
  const tabHeaders = navigation.querySelectorAll<HTMLElement>('.tab-header');
  let found = false;
  for (let i = 0; i < tabContents.length; i++) {
    const tabContent = tabContents[i]!;
    const tabHeader = tabHeaders[i]!;
    const isTargetTab = tabContent.id === id;

    found = found || isTargetTab;
    tabContent.classList.toggle('selected', isTargetTab);
    tabHeader.classList.toggle('selected', isTargetTab);
  }
  if (!found) {
    return false;
  }
  window.location.hash = id;
  return true;
}

function onHashChange() {
  const hash = window.location.hash.slice(1).toLowerCase();
  if (!selectTab(hash)) {
    selectTab('general');
  }
}

function setupTabs() {
  const tabContents = document.querySelectorAll('#content > div');
  for (const tabContent of tabContents) {
    const contentHeader =
        tabContent.querySelector<HTMLElement>('.content-header');
    assert(contentHeader);
    const tabName = contentHeader.textContent;

    const tabHeader = document.createElement('div');
    tabHeader.className = 'tab-header';
    const button = document.createElement('button');
    button.textContent = tabName;
    tabHeader.appendChild(button);
    tabHeader.addEventListener('click', selectTab.bind(null, tabContent.id));
    const navigation = document.querySelector('#navigation');
    assert(navigation);
    navigation.appendChild(tabHeader);
  }
  onHashChange();
}

/**
 * Collects and displays info about the renderer process count and limit across
 * all profiles.
 */
async function loadProcessCountInfo() {
  assert(pageHandler);
  const {info} = await pageHandler.getProcessCountInfo();

  const processCountTotal =
      document.querySelector<HTMLElement>('#process-count-total');
  assert(processCountTotal);
  processCountTotal.innerText = String(info.rendererProcessCountTotal);

  const liveProcessesCountTotal =
      document.querySelector<HTMLElement>('#live-processes-count-total');
  assert(liveProcessesCountTotal);
  liveProcessesCountTotal.innerText =
      String(info.liveRendererProcessesCountTotal);

  const processCountForLimit =
      document.querySelector<HTMLElement>('#process-count-for-limit');
  assert(processCountForLimit);
  processCountForLimit.innerText = String(info.rendererProcessCountForLimit);

  const processLimit = document.querySelector<HTMLElement>('#process-limit');
  assert(processLimit);
  processLimit.innerText = String(info.rendererProcessLimit);

  const overProcessLimit =
      document.querySelector<HTMLElement>('#over-process-limit');
  assert(overProcessLimit);
  overProcessLimit.innerText =
      (info.rendererProcessCountForLimit >= info.rendererProcessLimit) ? 'Yes' :
                                                                         'No';
}

/**
 * Root of the WebContents tree.
 */
let treeViewRoot: CrTreeElement|null = null;

/**
 * Accumulators for tracking frame and process counts. Reset in
 * loadWebContentsInfo.
 */
let totalFrameCount: number = 0;
let totalCrossProcessFrameCount: number = 0;
let processIdSet: Set<number> = new Set();

/**
 * Initialize and return |treeViewRoot|.
 */
function getTreeViewRoot(): CrTreeElement {
  if (!treeViewRoot) {
    treeViewRoot = document.querySelector('cr-tree');
    assert(treeViewRoot);
    treeViewRoot.detail = {payload: {}, children: {}};
  }
  return treeViewRoot;
}

/**
 * Initialize and return a tree item representing a FrameInfo object and
 * recursively creates its subframe objects. For subframes, pass the parent
 * frame's process ID in `parentProcessId`.
 */
function frameToTreeItem(frame: FrameInfo, parentProcessId: number = -1):
    {item: CrTreeItemElement, count: number} {
  // Count out-of-process iframes.
  const isCrossProcessFrame: boolean =
      parentProcessId !== -1 && parentProcessId !== frame.processId;
  if (isCrossProcessFrame) {
    totalCrossProcessFrameCount++;
  }
  processIdSet.add(frame.processId);

  // Compose the string which will appear in the entry for this frame.
  const prefix = isCrossProcessFrame ? 'OOPIF' : 'Frame';
  let itemLabel = `${prefix}[${frame.processId}:${frame.routingId}]:`;
  if (frame.type === FrameInfo_Type.kBackForwardCache) {
    itemLabel += ` bfcached`;
  } else if (frame.type === FrameInfo_Type.kPrerender) {
    itemLabel += ` prerender`;
  }

  itemLabel += ` SI:${frame.siteInstance.id}`;
  itemLabel += `, SIG:${frame.siteInstance.siteInstanceGroupId}`;
  itemLabel += `, BI:${frame.siteInstance.browsingInstanceId}`;
  if (frame.siteInstance.locked) {
    itemLabel += ', locked';
  } else {
    itemLabel += ', unlocked';
  }
  if (frame.siteInstance.siteUrl) {
    itemLabel += `, site:${frame.siteInstance.siteUrl.url}`;
  }
  if (frame.siteInstance.processLockUrl) {
    itemLabel += `, lock:${frame.siteInstance.processLockUrl.url}`;
  }
  if (frame.siteInstance.requiresOriginKeyedProcess) {
    itemLabel += ', origin-keyed';
  }
  if (frame.siteInstance.isSandboxForIframes) {
    itemLabel += ', iframe-sandbox';
  }
  if (frame.siteInstance.isGuest) {
    itemLabel += ', guest';
  }
  if (frame.siteInstance.isPdf) {
    itemLabel += ', pdf';
  }
  // TODO(crbug.com/398265332): only show the non-default case.
  if (frame.siteInstance.areJavascriptOptimizersEnabled) {
    itemLabel += ', js-opt-on';
  } else {
    itemLabel += ', js-opt-off';
  }
  if (frame.siteInstance.storagePartition) {
    itemLabel += `, partition:${frame.siteInstance.storagePartition}`;
  }
  if (frame.lastCommittedUrl) {
    itemLabel += ` | url: ${frame.lastCommittedUrl.url}`;
  }

  const item = document.createElement('cr-tree-item');
  item.label = itemLabel;
  item.detail = {payload: {}, children: {}};
  item.toggleAttribute(MAY_HAVE_CHILDREN_ATTR, true);
  item.expanded = true;

  let frameCount = 1;
  for (const subframe of frame.subframes) {
    const result = frameToTreeItem(subframe, frame.processId);
    const subItem = result.item;
    const count = result.count;

    frameCount += count;
    item.add(subItem);
  }

  return {item: item, count: frameCount};
}

/**
 * Initialize and return a tree item representing the WebContentsInfo object
 * and contains all frames in it as a subtree.
 */
function webContentsToTreeItem(webContents: WebContentsInfo):
    CrTreeItemElement {
  let itemLabel = 'WebContents: ';
  if (webContents.title.length > 0) {
    itemLabel += webContents.title + ', ';
  }

  const item = document.createElement('cr-tree-item');
  item.label = itemLabel;
  item.detail = {payload: {}, children: {}};
  item.toggleAttribute(MAY_HAVE_CHILDREN_ATTR, true);
  item.expanded = true;

  const result = frameToTreeItem(webContents.rootFrame);
  const rootItem = result.item;
  const activeCount = result.count;
  item.add(rootItem);

  // Add data for all root nodes retrieved from back-forward cache.
  let cachedCount = 0;
  for (const cachedRoot of webContents.bfcachedRootFrames) {
    const cachedResult = frameToTreeItem(cachedRoot);
    item.add(cachedResult.item);
    cachedCount++;
  }

  // Add data for all root nodes in prerendered pages.
  let prerenderCount = 0;
  for (const cachedRoot of webContents.prerenderRootFrames) {
    const cachedResult = frameToTreeItem(cachedRoot);
    item.add(cachedResult.item);
    prerenderCount++;
  }

  // Builds a string according to English pluralization rules:
  // buildCountString(0, 'frame') => "0 frames"
  // buildCountString(1, 'frame') => "1 frame"
  // buildCountString(2, 'frame') => "2 frames"
  const buildCountString = ((count: number, name: string) => {
    return `${count} ${name}` + (count !== 1 ? 's' : '');
  });

  itemLabel += buildCountString(activeCount, 'active frame');
  if (cachedCount > 0) {
    itemLabel += ', ' + buildCountString(cachedCount, 'bfcached root');
  }
  if (prerenderCount > 0) {
    itemLabel += ', ' + buildCountString(prerenderCount, 'prerender root');
  }
  item.label = itemLabel;

  totalFrameCount += activeCount + cachedCount + prerenderCount;

  return item;
}

/**
 * This is a callback which is invoked when the data for WebContents
 * associated with the browser profile is received from the browser process.
 */
function populateWebContentsTab(infos: WebContentsInfo[]) {
  const tree = getTreeViewRoot();

  // Clear the tree first before populating it with the new content.
  tree.items.forEach(item => tree.removeTreeItem(item));

  for (const webContents of infos) {
    const item = webContentsToTreeItem(webContents);
    tree.add(item);
  }
}

/**
 * Function which retrieves the data for all WebContents associated with the
 * current browser profile. The result is passed to populateWebContentsTab.
 */
async function loadWebContentsInfo() {
  // Reset frame counts.
  totalFrameCount = 0;
  totalCrossProcessFrameCount = 0;
  processIdSet = new Set();

  assert(pageHandler);
  const {infos} = await pageHandler.getAllWebContentsInfo();
  populateWebContentsTab(infos);

  // Post tab, frame, and process counts.
  const tabCount = document.querySelector<HTMLElement>('#tab-count');
  assert(tabCount);
  tabCount.innerText = String(infos.length);
  const frameCount = document.querySelector<HTMLElement>('#frame-count');
  assert(frameCount);
  frameCount.innerText = String(totalFrameCount);
  const oopifCount = document.querySelector<HTMLElement>('#oopif-count');
  assert(oopifCount);
  oopifCount.innerText = String(totalCrossProcessFrameCount);
  const processCount =
      document.querySelector<HTMLElement>('#profile-process-count');
  assert(processCount);
  processCount.innerText = String(processIdSet.size);
}

/**
 * Function which retrieves the currently active isolated origins and inserts
 * them into the page.  It organizes these origins into two lists: persisted
 * isolated origins, which are triggered by password entry and apply only
 * within the current profile, and global isolated origins, which apply to all
 * profiles.
 */
function loadIsolatedOriginInfo() {
  assert(pageHandler);
  // Retrieve any persistent isolated origins for the current profile. Insert
  // them into a list on the page if there is at least one such origin.
  pageHandler.getUserTriggeredIsolatedOrigins().then((response) => {
    const originCount = response.isolatedOrigins.length;
    if (!originCount) {
      return;
    }

    const userOrigins =
        document.querySelector<HTMLElement>('#user-triggered-isolated-origins');
    assert(userOrigins);
    userOrigins.textContent =
        'The following origins are isolated because you previously typed a ' +
        'password or logged in on these sites (' + originCount + ' total). ' +
        'Clear cookies or history to wipe this list; this takes effect ' +
        'after a restart.';

    const list = document.createElement('ul');
    for (const origin of response.isolatedOrigins) {
      const item = document.createElement('li');
      item.textContent = origin;
      list.appendChild(item);
    }

    userOrigins.appendChild(list);
  });

  pageHandler.getWebTriggeredIsolatedOrigins().then((response) => {
    const originCount = response.isolatedOrigins.length;
    if (!originCount) {
      return;
    }

    const webOrigins =
        document.querySelector<HTMLElement>('#web-triggered-isolated-origins');
    assert(webOrigins);
    webOrigins.textContent =
        'The following origins are isolated based on runtime heuristics ' +
        'triggered directly by web pages, such as Cross-Origin-Opener-Policy ' +
        'headers. Clear cookies or history to wipe this list; this takes ' +
        'effect after a restart.';

    const list = document.createElement('ul');
    for (const origin of response.isolatedOrigins) {
      const item = document.createElement('li');
      item.textContent = origin;
      list.appendChild(item);
    }

    webOrigins.appendChild(list);
  });

  // Retrieve global isolated origins and insert them into a separate list if
  // there is at least one such origin.  Since these origins may come from
  // multiple sources, include the source info for each origin in parens.
  pageHandler.getGloballyIsolatedOrigins().then((response) => {
    const originCount = response.isolatedOrigins.length;
    if (!originCount) {
      return;
    }

    const globalOrigins =
        document.querySelector<HTMLElement>('#global-isolated-origins');
    assert(globalOrigins);
    globalOrigins.textContent =
        'The following origins are isolated by default for all users (' +
        originCount + ' total).  A description of how each origin was ' +
        ' activated is provided in parentheses.';

    const list = document.createElement('ul');
    for (const originInfo of response.isolatedOrigins) {
      const item = document.createElement('li');
      item.textContent = `${originInfo.origin} (${originInfo.source})`;
      list.appendChild(item);
    }
    globalOrigins.appendChild(list);
  });
}

document.addEventListener('DOMContentLoaded', function() {
  // Set up Mojo interface to the backend.
  pageHandler = ProcessInternalsHandler.getRemote();
  assert(pageHandler);

  // Set up the tabbed UI.
  setupTabs();

  // Populate the process count and limit info.
  loadProcessCountInfo();

  const refreshProcessInfoButton =
      document.querySelector<HTMLElement>('#refresh-process-info');
  assert(refreshProcessInfoButton);
  refreshProcessInfoButton.addEventListener('click', loadProcessCountInfo);

  // Get the ProcessPerSite mode and populate it.
  pageHandler.getProcessPerSiteMode().then((response) => {
    const sharingMode =
        document.querySelector<HTMLElement>('#process-per-site-mode');
    assert(sharingMode);
    sharingMode.innerText = response.mode;
  });

  // Get the Site Isolation mode and populate it.
  pageHandler.getIsolationMode().then((response) => {
    const isolationMode =
        document.querySelector<HTMLElement>('#isolation-mode');
    assert(isolationMode);
    isolationMode.innerText = response.mode;
  });
  loadIsolatedOriginInfo();

  // Start loading the information about WebContents.
  loadWebContentsInfo();

  const refreshFrameTreesButton =
      document.querySelector<HTMLElement>('#refresh-frame-trees');
  assert(refreshFrameTreesButton);
  refreshFrameTreesButton.addEventListener('click', loadWebContentsInfo);
});
