// 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';

function $(id) {
  // Disable getElementById restriction here, because this UI uses non valid
  // selectors that don't work with querySelector().
  // eslint-disable-next-line no-restricted-properties
  const el = document.getElementById(id);
  if (!el) {
    return null;
  }
  assert(el instanceof HTMLElement);
  return el;
}

const MIN_VERSION_TAB_CLOSE = 25;
const MIN_VERSION_TARGET_ID = 26;
const MIN_VERSION_NEW_TAB = 29;
const MIN_VERSION_TAB_ACTIVATE = 30;
const WEBRTC_SERIAL = 'WEBRTC';
let HOST_CHROME_VERSION;

const queryParamsObject = {};
let browserInspector = 'chrome://tracing';
let browserInspectorTitle = 'trace';
let staleDataCounter = 0;

(function() {
const queryParams = window.location.search;
if (!queryParams) {
  return;
}
const params = queryParams.substring(1).split('&');
for (let i = 0; i < params.length; ++i) {
  const pair = params[i].split('=');
  queryParamsObject[pair[0]] = pair[1];
}

if ('browser-inspector' in queryParamsObject) {
  browserInspector = queryParamsObject['browser-inspector'];
  browserInspectorTitle = 'inspect';
}
})();

function isVersionNewerThanHost(version) {
  if (!HOST_CHROME_VERSION) {
    return false;
  }
  version = version.split('.').map(s => Number(s) || 0);
  for (let i = 0; i < HOST_CHROME_VERSION.length; i++) {
    if (i > version.length) {
      return false;
    }
    if (HOST_CHROME_VERSION[i] > version[i]) {
      return false;
    }
    if (HOST_CHROME_VERSION[i] < version[i]) {
      return true;
    }
  }
  return false;
}

function sendCommand(command, args) {
  chrome.send(command, Array.prototype.slice.call(arguments, 1));
}

function sendTargetCommand(command, target) {
  sendCommand(command, target.source, target.id);
}

function removeChildren(element_id) {
  const element = $(element_id);
  element.textContent = '';
}

function onload() {
  const tabContents = document.querySelectorAll('#content > div');
  for (let i = 0; i !== tabContents.length; i++) {
    const tabContent = tabContents[i];
    const tabName = tabContent.querySelector('.content-header').textContent;

    const tabHeader = document.createElement('div');
    tabHeader.className = 'tab-header';
    tabHeader.id = 'tab-'.concat(tabContent.id);
    const button = document.createElement('button');
    button.textContent = tabName;
    tabHeader.appendChild(button);
    tabHeader.addEventListener('click', selectTab.bind(null, tabContent.id));
    $('navigation').appendChild(tabHeader);
  }
  $('tab-native-ui').hidden = true;
  onHashChange();
  initSettings();
  sendCommand('init-ui');
  initStaleDataWatch();
}

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

/**
 * @param {string} id Tab id.
 * @return {boolean} True if successful.
 */
function selectTab(id) {
  const tabContents = document.querySelectorAll('#content > div');
  const tabHeaders = $('navigation').querySelectorAll('.tab-header');
  let found = false;
  for (let i = 0; i !== tabContents.length; i++) {
    const tabContent = tabContents[i];
    const tabHeader = tabHeaders[i];
    if (tabContent.id === id) {
      tabContent.classList.add('selected');
      tabHeader.classList.add('selected');
      found = true;
    } else {
      tabContent.classList.remove('selected');
      tabHeader.classList.remove('selected');
    }
  }
  if (!found) {
    return false;
  }
  window.location.hash = id;
  return true;
}

function populateTargets(source, data) {
  if (source === 'local') {
    populateLocalTargets(data);
  } else if (source === 'remote') {
    populateRemoteTargets(data);
  } else {
    console.error('Unknown source type: ' + source);
  }
}

function populateNativeUITargets(data) {
  removeChildren('native-ui-list');
  for (let i = 0; i < data.length; i++) {
    addToNativeUIList(data[i]);
  }
}

function showNativeUILaunchButton(enabled) {
  $('native-ui').hidden = false;
  $('tab-native-ui').hidden = false;
  $('launch-ui-devtools').hidden = false;
  $('launch-ui-devtools').disabled = !enabled;
  $('ui-devtools-disabled-text').hidden = enabled;
  $('ui-devtools-enabled-text').hidden = !enabled;
}

function setHostVersion(version) {
  version = version.split('.').map(s => Number(s) || 0);
  HOST_CHROME_VERSION = version;
}

function populateLocalTargets(data) {
  removeChildren('pages-list');
  removeChildren('extensions-list');
  removeChildren('apps-list');
  removeChildren('workers-list');
  removeChildren('service-workers-list');
  removeChildren('shared-storage-worklets-list');
  removeChildren('others-list');

  data.sort((a, b) => a.name.localeCompare(b.name));

  for (let i = 0; i < data.length; i++) {
    if (data[i].type === 'page') {
      addToPagesList(data[i]);
    } else if (data[i].type === 'background_page') {
      addToExtensionsList(data[i]);
    } else if (data[i].type === 'app') {
      addToAppsList(data[i]);
    } else if (data[i].type === 'shared_worker') {
      addToWorkersList(data[i]);
    } else if (data[i].type === 'service_worker') {
      addToServiceWorkersList(data[i]);
    } else if (data[i].type === 'shared_storage_worklet') {
      addToSharedStorageWorkletsList(data[i]);
    } else {
      addToOthersList(data[i]);
    }
  }
}

function showIncognitoWarning() {
  $('devices-incognito').hidden = false;
}

function alreadyDisplayed(element, data) {
  const json = JSON.stringify(data);
  if (element.cachedJSON === json) {
    return true;
  }
  element.cachedJSON = json;
  return false;
}

function updateBrowserVisibility(browserSection) {
  const icon = browserSection.querySelector('.used-for-port-forwarding');
  browserSection.hidden = !browserSection.querySelector('.open') &&
      !browserSection.querySelector('.row') && (!icon || icon.hidden);
}

function updateUsernameVisibility(deviceSection) {
  const users = new Set();
  const browsers = deviceSection.querySelectorAll('.browser');

  Array.prototype.forEach.call(browsers, function(browserSection) {
    if (!browserSection.hidden) {
      const browserUser = browserSection.querySelector('.browser-user');
      if (browserUser) {
        users.add(browserUser.textContent);
      }
    }
  });
  const hasSingleUser = users.size <= 1;

  Array.prototype.forEach.call(browsers, function(browserSection) {
    const browserUser = browserSection.querySelector('.browser-user');
    if (browserUser) {
      browserUser.hidden = hasSingleUser;
    }
  });
}

function populateRemoteTargets(devices) {
  staleDataCounter = 0;
  $('devices-stale').hidden = true;
  $('devices-not-responding').hidden = true;

  if (!devices) {
    return;
  }

  if ($('config-dialog').open) {
    window.holdDevices = devices;
    return;
  }

  function browserCompare(a, b) {
    if (a.adbBrowserName !== b.adbBrowserName) {
      return a.adbBrowserName < b.adbBrowserName;
    }
    if (a.adbBrowserVersion !== b.adbBrowserVersion) {
      return a.adbBrowserVersion < b.adbBrowserVersion;
    }
    return a.id < b.id;
  }

  function insertBrowser(browserList, browser) {
    for (let sibling = browserList.firstElementChild; sibling;
         sibling = sibling.nextElementSibling) {
      if (browserCompare(browser, sibling)) {
        browserList.insertBefore(browser, sibling);
        return;
      }
    }
    browserList.appendChild(browser);
  }

  const deviceList = $('devices-list');
  if (alreadyDisplayed(deviceList, devices)) {
    return;
  }

  function removeObsolete(validIds, section) {
    if (validIds.indexOf(section.id) < 0) {
      section.remove();
    }
  }

  const newDeviceIds = devices.map(function(d) {
    return d.id;
  });
  Array.prototype.forEach.call(
      deviceList.querySelectorAll('.device'),
      removeObsolete.bind(null, newDeviceIds));

  $('devices-help').hidden = !!devices.length;

  for (let d = 0; d < devices.length; d++) {
    const device = devices[d];

    let deviceSection = $(device.id);
    if (!deviceSection) {
      deviceSection = document.createElement('div');
      deviceSection.id = device.id;
      deviceSection.className = 'device';
      deviceList.appendChild(deviceSection);

      const deviceHeader = document.createElement('div');
      deviceHeader.className = 'device-header';
      deviceSection.appendChild(deviceHeader);

      const deviceName = document.createElement('div');
      deviceName.className = 'device-name';
      deviceHeader.appendChild(deviceName);

      const deviceSerial = document.createElement('div');
      deviceSerial.className = 'device-serial';
      const serial = device.adbSerial.toUpperCase();
      deviceSerial.textContent = '#' + serial;
      deviceHeader.appendChild(deviceSerial);

      if (serial === WEBRTC_SERIAL) {
        deviceHeader.classList.add('hidden');
      }

      const devicePorts = document.createElement('div');
      devicePorts.className = 'device-ports';
      deviceHeader.appendChild(devicePorts);

      const browserList = document.createElement('div');
      browserList.className = 'browsers';
      deviceSection.appendChild(browserList);

      const authenticating = document.createElement('div');
      authenticating.className = 'device-auth';
      deviceSection.appendChild(authenticating);
    }

    if (alreadyDisplayed(deviceSection, device)) {
      continue;
    }

    deviceSection.querySelector('.device-name').textContent = device.adbModel;
    deviceSection.querySelector('.device-auth').textContent =
        device.adbConnected ? '' : device.adbUnauthorized ?
                              'Pending authentication: please accept ' +
            'debugging session on the device.' : device.adbLocked ?
            'Device is locked.' : 'Device is not responding.';

    const browserList = deviceSection.querySelector('.browsers');
    const newBrowserIds = device.browsers.map(function(b) {
      return b.id;
    });
    Array.prototype.forEach.call(
        browserList.querySelectorAll('.browser'),
        removeObsolete.bind(null, newBrowserIds));

    for (let b = 0; b < device.browsers.length; b++) {
      const browser = device.browsers[b];
      const majorChromeVersion = browser.adbBrowserChromeVersion;
      let pageList;
      let browserSection = $(browser.id);
      const browserNeedsFallback =
          isVersionNewerThanHost(browser.adbBrowserVersion);
      if (browserSection) {
        pageList = browserSection.querySelector('.pages');
      } else {
        browserSection = document.createElement('div');
        browserSection.id = browser.id;
        browserSection.className = 'browser';
        insertBrowser(browserList, browserSection);

        const browserHeader = document.createElement('div');
        browserHeader.className = 'browser-header';

        const browserName = document.createElement('div');
        browserName.className = 'browser-name';
        browserHeader.appendChild(browserName);
        // Localhost targets are always named "Target".
        // Let's use the ID instead as it's more expressive.
        browserName.textContent = browser.adbBrowserName === 'Target' ?
            browser.id :
            browser.adbBrowserName;

        if (browser.adbBrowserVersion) {
          browserName.textContent += ' (' + browser.adbBrowserVersion + ')';
        }
        if (browser.adbBrowserUser) {
          const browserUser = document.createElement('div');
          browserUser.className = 'browser-user';
          browserUser.textContent = browser.adbBrowserUser;
          browserHeader.appendChild(browserUser);
        }
        browserSection.appendChild(browserHeader);

        if (browserNeedsFallback) {
          const browserFallbackNote = document.createElement('div');
          browserFallbackNote.className = 'browser-fallback-note';
          browserFallbackNote.textContent =
              '\u26A0 Remote browser is newer than client browser. ' +
              'Try `inspect fallback` if inspection fails.';
          browserSection.appendChild(browserFallbackNote);
        }

        if (majorChromeVersion >= MIN_VERSION_NEW_TAB) {
          const newPage = document.createElement('div');
          newPage.className = 'open';

          const newPageUrl = document.createElement('input');
          newPageUrl.type = 'text';
          newPageUrl.placeholder = 'Open tab with url';
          newPage.appendChild(newPageUrl);

          const openHandler = function(sourceId, browserId, input) {
            sendCommand(
                'open', sourceId, browserId, input.value || 'about:blank');
            input.value = '';
          }.bind(null, browser.source, browser.id, newPageUrl);
          newPageUrl.addEventListener('keyup', function(handler, event) {
            if (event.key === 'Enter' && event.target.value) {
              handler();
            }
          }.bind(null, openHandler), true);

          const newPageButton = document.createElement('button');
          newPageButton.textContent = 'Open';
          newPage.appendChild(newPageButton);
          newPageButton.addEventListener('click', openHandler, true);

          browserHeader.appendChild(newPage);
        }

        const portForwardingInfo = document.createElement('div');
        portForwardingInfo.className = 'used-for-port-forwarding';
        portForwardingInfo.hidden = true;
        portForwardingInfo.title = 'This browser is used for port ' +
            'forwarding. Closing it will drop current connections.';
        browserHeader.appendChild(portForwardingInfo);

        const link = document.createElement('span');
        link.classList.add('action');
        link.setAttribute('tabindex', 1);
        link.textContent = browserInspectorTitle;
        browserHeader.appendChild(link);
        link.addEventListener(
            'click',
            sendCommand.bind(
                null, 'inspect-browser', browser.source, browser.id,
                browserInspector),
            false);

        pageList = document.createElement('div');
        pageList.className = 'list pages';
        browserSection.appendChild(pageList);
      }

      if (!alreadyDisplayed(browserSection, browser)) {
        pageList.textContent = '';
        for (let p = 0; p < browser.pages.length; p++) {
          const page = browser.pages[p];
          // Attached targets have no unique id until Chrome 26. For such
          // targets it is impossible to activate existing DevTools window.
          page.hasNoUniqueId = page.attached && majorChromeVersion &&
              majorChromeVersion < MIN_VERSION_TARGET_ID;
          const row = addTargetToList(page, pageList, ['name', 'url']);
          if (page['description']) {
            addWebViewDetails(row, page);
          } else {
            addFavicon(row, page);
          }
          if (majorChromeVersion >= MIN_VERSION_TAB_ACTIVATE) {
            addActionLink(
                row, 'focus tab',
                sendTargetCommand.bind(null, 'activate', page), false);
          }
          if (majorChromeVersion) {
            addActionLink(
                row, 'reload', sendTargetCommand.bind(null, 'reload', page),
                page.attached);
          }
          if (majorChromeVersion >= MIN_VERSION_TAB_CLOSE) {
            addActionLink(
                row, 'close', sendTargetCommand.bind(null, 'close', page),
                false);
          }
          addActionLink(
              row, 'inspect fallback',
              sendTargetCommand.bind(null, 'inspect-fallback', page),
              page.hasNoUniqueId || page.adbAttachedForeign,
              'Best-effort fallback to debug the target using this browser instance\'s potentially mismatching DevTools version.');
        }
      }
      updateBrowserVisibility(browserSection);
    }
    updateUsernameVisibility(deviceSection);
  }
}

function addToPagesList(data) {
  const row = addTargetToList(data, $('pages-list'), ['name', 'url']);
  addFavicon(row, data);
  if (data.guests) {
    addGuestViews(row, data.guests);
  }
}

function addToExtensionsList(data) {
  const row = addTargetToList(data, $('extensions-list'), ['name', 'url']);
  addFavicon(row, data);
  if (data.guests) {
    addGuestViews(row, data.guests);
  }
}

function addToAppsList(data) {
  const row = addTargetToList(data, $('apps-list'), ['name', 'url']);
  addFavicon(row, data);
  if (data.guests) {
    addGuestViews(row, data.guests);
  }
}

function addGuestViews(row, guests) {
  Array.prototype.forEach.call(guests, function(guest) {
    const guestRow = addTargetToList(guest, row, ['name', 'url']);
    guestRow.classList.add('guest');
    addFavicon(guestRow, guest);
  });
}

function addToWorkersList(data) {
  const row =
      addTargetToList(data, $('workers-list'), ['name', 'description', 'url']);

  let description;
  try {
    description = JSON.parse(data.description);
  } catch (e) {
    // Not a JSON description, ignore and proceed.
  }

  if (description && description.extendedLifetime) {
    const nameElement = row.querySelector('.name');
    if (nameElement) {
      const label = document.createElement('span');
      label.className = 'extended-lifetime-label';
      label.textContent = 'Extended Lifetime';
      nameElement.appendChild(document.createTextNode(' '));
      nameElement.appendChild(label);
    }

    // Hide the raw JSON description.
    const descriptionElement = row.querySelector('.description');
    if (descriptionElement) {
      descriptionElement.style.display = 'none';
    }
  }

  addActionLink(
      row, 'terminate', sendTargetCommand.bind(null, 'close', data), false);
}

function addToServiceWorkersList(data) {
  const row = addTargetToList(
      data, $('service-workers-list'), ['name', 'description', 'url']);
  addActionLink(
      row, 'terminate', sendTargetCommand.bind(null, 'close', data), false);
}

function addToSharedStorageWorkletsList(data) {
  const row = addTargetToList(
      data, $('shared-storage-worklets-list'), ['name', 'description', 'url']);
  // TODO(yaoxia): add the "terminate" link when the backend supports it
}

function addToOthersList(data) {
  addTargetToList(data, $('others-list'), ['url']);
}

function addToNativeUIList(data) {
  addTargetToList(data, $('native-ui-list'), ['name', 'url']);
}

function formatValue(data, property) {
  let value = data[property];

  if (property === 'name' && value === '') {
    value = 'untitled';
  }

  let text = value ? String(value) : '';
  if (text.length > 100) {
    text = text.substring(0, 100) + '\u2026';
  }

  const div = document.createElement('div');
  div.textContent = text;
  div.className = property;
  return div;
}

function addFavicon(row, data) {
  const favicon = document.createElement('img');
  if (data['faviconUrl']) {
    favicon.src = data['faviconUrl'];
  }
  const propertiesBox = row.querySelector('.properties-box');
  propertiesBox.insertBefore(favicon, propertiesBox.firstChild);
}

function addWebViewDetails(row, data) {
  let webview;
  try {
    webview = JSON.parse(data['description']);
  } catch (e) {
    return;
  }
  addWebViewDescription(row, webview);
  if (data.adbScreenWidth && data.adbScreenHeight) {
    addWebViewThumbnail(
        row, webview, data.adbScreenWidth, data.adbScreenHeight);
  }
}

function addWebViewDescription(row, webview) {
  const viewStatus = {visibility: '', position: '', size: ''};
  if (!webview.empty) {
    if (webview.attached && !webview.visible) {
      viewStatus.visibility = 'hidden';
    } else if (!webview.attached) {
      viewStatus.visibility = 'detached';
    }
    viewStatus.size = 'size ' + webview.width + ' \u00d7 ' + webview.height;
  } else {
    viewStatus.visibility = 'empty';
  }
  if (webview.never_attached) {
    viewStatus.visibility += ' never-attached';
  }
  if (webview.attached) {
    viewStatus.position =
        'at (' + webview.screenX + ', ' + webview.screenY + ')';
  }

  const subRow = document.createElement('div');
  subRow.className = 'subrow webview';
  if (webview.empty || !webview.attached || !webview.visible) {
    subRow.className += ' invisible-view';
  }
  if (viewStatus.visibility) {
    subRow.appendChild(formatValue(viewStatus, 'visibility'));
  }
  if (viewStatus.position) {
    subRow.appendChild(formatValue(viewStatus, 'position'));
  }
  subRow.appendChild(formatValue(viewStatus, 'size'));
  const subrowBox = row.querySelector('.subrow-box');
  subrowBox.insertBefore(subRow, row.querySelector('.actions'));
}

function addWebViewThumbnail(row, webview, screenWidth, screenHeight) {
  const maxScreenRectSize = 50;
  let screenRectWidth;
  let screenRectHeight;

  const aspectRatio = screenWidth / screenHeight;
  if (aspectRatio < 1) {
    screenRectWidth = Math.round(maxScreenRectSize * aspectRatio);
    screenRectHeight = maxScreenRectSize;
  } else {
    screenRectWidth = maxScreenRectSize;
    screenRectHeight = Math.round(maxScreenRectSize / aspectRatio);
  }

  const thumbnail = document.createElement('div');
  thumbnail.className = 'webview-thumbnail';
  const thumbnailWidth = 3 * screenRectWidth;
  const thumbnailHeight = 60;
  thumbnail.style.width = thumbnailWidth + 'px';
  thumbnail.style.height = thumbnailHeight + 'px';

  const screenRect = document.createElement('div');
  screenRect.className = 'screen-rect';
  screenRect.style.left = screenRectWidth + 'px';
  screenRect.style.top = (thumbnailHeight - screenRectHeight) / 2 + 'px';
  screenRect.style.width = screenRectWidth + 'px';
  screenRect.style.height = screenRectHeight + 'px';
  thumbnail.appendChild(screenRect);

  if (!webview.empty && webview.attached) {
    const viewRect = document.createElement('div');
    viewRect.className = 'view-rect';
    if (!webview.visible) {
      viewRect.classList.add('hidden');
    }
    function percent(ratio) {
      return ratio * 100 + '%';
    }
    viewRect.style.left = percent(webview.screenX / screenWidth);
    viewRect.style.top = percent(webview.screenY / screenHeight);
    viewRect.style.width = percent(webview.width / screenWidth);
    viewRect.style.height = percent(webview.height / screenHeight);
    screenRect.appendChild(viewRect);
  }

  const propertiesBox = row.querySelector('.properties-box');
  propertiesBox.insertBefore(thumbnail, propertiesBox.firstChild);
}

function addTargetToList(data, list, properties) {
  const row = document.createElement('div');
  row.className = 'row';
  row.targetId = data.id;

  const propertiesBox = document.createElement('div');
  propertiesBox.className = 'properties-box';
  row.appendChild(propertiesBox);

  const subrowBox = document.createElement('div');
  subrowBox.className = 'subrow-box';
  propertiesBox.appendChild(subrowBox);

  const subrow = document.createElement('div');
  subrow.className = 'subrow';
  subrowBox.appendChild(subrow);

  for (let j = 0; j < properties.length; j++) {
    subrow.appendChild(formatValue(data, properties[j]));
  }

  const actionBox = document.createElement('div');
  actionBox.className = 'actions';
  subrowBox.appendChild(actionBox);

  if (!data.isNative && !data.hasCustomInspectAction &&
      data.type !== 'iframe') {
    addActionLink(
        row, 'inspect', sendTargetCommand.bind(null, 'inspect', data),
        data.hasNoUniqueId || data.adbAttachedForeign);
    if (data.type === 'page') {
      addActionLink(
          row, 'pause', sendTargetCommand.bind(null, 'pause', data),
          data.hasNoUniqueId || data.adbAttachedForeign);
    }
  }

  list.appendChild(row);
  return row;
}

function addActionLink(row, text, handler, opt_disabled, opt_title) {
  const link = document.createElement('span');
  link.classList.add('action');
  link.setAttribute('tabindex', 1);
  if (opt_title) {
    link.title = opt_title;
  }
  if (opt_disabled) {
    link.classList.add('disabled');
  } else {
    link.classList.remove('disabled');
  }

  link.textContent = text;
  link.addEventListener('click', handler, true);
  function handleKey(e) {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handler();
    }
  }
  link.addEventListener('keydown', handleKey, true);
  row.querySelector('.actions').appendChild(link);
}

function initSettings() {
  checkboxSendsCommand(
      'discover-usb-devices-enable', 'set-discover-usb-devices-enabled');
  checkboxSendsCommand('port-forwarding-enable', 'set-port-forwarding-enabled');
  checkboxSendsCommand(
      'discover-tcp-devices-enable', 'set-discover-tcp-targets-enabled');

  $('launch-ui-devtools')
      .addEventListener('click', sendCommand.bind(null, 'launch-ui-devtools'));
  checkboxSendsCommand('bubble-locking-checkbox', 'set-bubble-locking');

  $('port-forwarding-config-open')
      .addEventListener('click', openPortForwardingConfig);
  $('tcp-discovery-config-open').addEventListener('click', openTargetsConfig);
  $('config-dialog-close').addEventListener('click', function() {
    $('config-dialog').commit(true);
  });
  $('node-frontend')
      .addEventListener('click', sendCommand.bind(null, 'open-node-frontend'));
}

function initStaleDataWatch() {
  let lastFocus = true;

  setInterval(() => {
    const newFocus = document.hasFocus();
    if (newFocus !== lastFocus) {
      lastFocus = newFocus;
      sendCommand('set-focus', newFocus);
      staleDataCounter = 0;
    } else {
      staleDataCounter++;
      if (staleDataCounter > 3) {
        // Unhide appropriate message.
        if (newFocus) {
          $('devices-stale').hidden = true;
          $('devices-not-responding').hidden = false;
        } else {
          $('devices-stale').hidden = false;
          $('devices-not-responding').hidden = true;
        }
      }
    }
  }, 5000);
}

function checkboxHandler(command, event) {
  sendCommand(command, event.target.checked);
}

function checkboxSendsCommand(id, command) {
  $(id).addEventListener('change', checkboxHandler.bind(null, command));
}

function handleKey(event) {
  switch (event.keyCode) {
    case 13:  // Enter
      const dialog = $('config-dialog');
      if (event.target.nodeName === 'INPUT') {
        const line = event.target.parentNode;
        if (!line.classList.contains('fresh') ||
            line.classList.contains('empty')) {
          dialog.commit(true);
        } else {
          commitFreshLineIfValid(true /* select new line */);
          dialog.commit(false);
        }
      } else {
        dialog.commit(true);
      }
      break;
  }
}

function commitDialog(commitHandler, shouldClose) {
  const element = $('config-dialog');
  if (element.open && shouldClose) {
    element.onclose = null;
    element.close();
    document.removeEventListener('keyup', handleKey);
    if (window.holdDevices) {
      populateRemoteTargets(window.holdDevices);
      delete window.holdDevices;
    }
  }
  commitFreshLineIfValid();
  commitHandler();
}

function openConfigDialog(dialogClass, commitHandler, lineFactory, data) {
  const dialog = $('config-dialog');
  if (dialog.open) {
    return;
  }

  dialog.className = dialogClass;
  dialog.classList.add('config');

  document.addEventListener('keyup', handleKey);
  dialog.commit = commitDialog.bind(null, commitHandler);
  dialog.onclose = commitDialog.bind(null, commitHandler, true);
  $('button-done').onclick = dialog.onclose;

  const list = $('config-dialog').querySelector('.list');
  list.textContent = '';

  list.createRow = appendRow.bind(null, list, lineFactory);
  for (const key in data) {
    list.createRow(key, data[key]);
  }
  list.createRow(null, null);

  dialog.showModal();
  const defaultFocus = dialog.querySelector('.fresh .preselected');
  if (defaultFocus) {
    defaultFocus.focus();
  } else {
    doneButton.focus();
  }
}

function openPortForwardingConfig() {
  function createPortForwardingConfigLine(port, location) {
    const line = document.createElement('div');
    line.className = 'port-forwarding-pair config-list-row';

    const portInput =
        createConfigField(port, 'port preselected', 'Port', validatePort);
    line.appendChild(portInput);

    const locationInput = createConfigField(
        location, 'location', 'IP address and port', validateLocation);
    locationInput.classList.add('primary');
    line.appendChild(locationInput);
    return line;
  }

  function commitPortForwardingConfig() {
    const config = {};
    filterList(['.port', '.location'], function(port, location) {
      config[port] = location;
    });
    sendCommand('set-port-forwarding-config', config);
  }

  openConfigDialog(
      'port-forwarding', commitPortForwardingConfig,
      createPortForwardingConfigLine, window.portForwardingConfig);
}

function openTargetsConfig() {
  function createTargetDiscoveryConfigLine(index, targetDiscovery) {
    const line = document.createElement('div');
    line.className = 'target-discovery-line config-list-row';

    const locationInput = createConfigField(
        targetDiscovery, 'location preselected', 'IP address and port',
        validateLocation);
    locationInput.classList.add('primary');
    line.appendChild(locationInput);
    return line;
  }

  function commitTargetDiscoveryConfig() {
    const entries = [];
    filterList(['.location'], function(location) {
      entries.push(location);
    });
    sendCommand('set-tcp-discovery-config', entries);
  }

  openConfigDialog(
      'target-discovery', commitTargetDiscoveryConfig,
      createTargetDiscoveryConfigLine, window.targetDiscoveryConfig);
}

function filterList(fieldSelectors, callback) {
  const lines = $('config-dialog').querySelectorAll('.config-list-row');
  for (let i = 0; i !== lines.length; i++) {
    const line = lines[i];
    const values = [];
    for (const selector of fieldSelectors) {
      const input = line.querySelector(selector);
      const value = input.classList.contains('invalid') ? input.lastValidValue :
                                                          input.value;
      if (!value) {
        break;
      }
      values.push(value);
    }
    if (values.length === fieldSelectors.length) {
      callback.apply(null, values);
    }
  }
}

function updateCheckbox(id, enabled) {
  const checkbox = $(id);
  checkbox.checked = !!enabled;
  checkbox.disabled = false;
}

function updateDiscoverUsbDevicesEnabled(enabled) {
  updateCheckbox('discover-usb-devices-enable', enabled);
}

function updatePortForwardingEnabled(enabled) {
  updateCheckbox('port-forwarding-enable', enabled);
  $('infobar').classList.toggle('show', enabled);
  $('infobar').scrollIntoView();
}

function updatePortForwardingConfig(config) {
  window.portForwardingConfig = config;
  $('port-forwarding-config-open').disabled = !config;
}

function updateTCPDiscoveryEnabled(enabled) {
  updateCheckbox('discover-tcp-devices-enable', enabled);
}

function updateTCPDiscoveryConfig(config) {
  window.targetDiscoveryConfig = config;
  $('tcp-discovery-config-open').disabled = !config;
}

function updateBubbleLockingCheckbox(enabled) {
  updateCheckbox('bubble-locking-checkbox', enabled);
}

function appendRow(list, lineFactory, key, value) {
  const line = lineFactory(key, value);
  line.lastElementChild.addEventListener('keydown', function(e) {
    if (e.key === 'Tab' && !hasKeyModifiers(e) &&
        line.classList.contains('fresh') && !line.classList.contains('empty')) {
      // Tabbing forward on the fresh line, try create a new empty one.
      if (commitFreshLineIfValid(true)) {
        e.preventDefault();
      }
    }
  });

  const lineDelete = document.createElement('div');
  lineDelete.className = 'close-button';
  lineDelete.addEventListener('click', function() {
    const newSelection = line.nextElementSibling || line.previousElementSibling;
    selectLine(newSelection, true);
    line.parentNode.removeChild(line);
    $('config-dialog').commit(false);
  });
  line.appendChild(lineDelete);

  line.addEventListener('click', selectLine.bind(null, line, true));
  line.addEventListener('focus', selectLine.bind(null, line, true));
  checkEmptyLine(line);

  if (!key && !value) {
    line.classList.add('fresh');
  }

  return list.appendChild(line);
}

function validatePort(input) {
  const match = input.value.match(/^(\d+)$/);
  if (!match) {
    return false;
  }
  const port = parseInt(match[1]);
  if (port < 1024 || 65535 < port) {
    return false;
  }

  const inputs = document.querySelectorAll('input.port:not(.invalid)');
  for (let i = 0; i !== inputs.length; ++i) {
    if (inputs[i] === input) {
      break;
    }
    if (parseInt(inputs[i].value) === port) {
      return false;
    }
  }
  return true;
}

function validateLocation(input) {
  const match = input.value.match(/^([a-zA-Z0-9\.\-_]+):(\d+)$/);
  if (!match) {
    return false;
  }
  const port = parseInt(match[2]);
  return port <= 65535;
}

function createConfigField(value, className, hint, validate) {
  const input = document.createElement('input');
  input.className = className;
  input.type = 'text';
  input.placeholder = hint;
  input.value = value || '';
  input.lastValidValue = value || '';

  function checkInput() {
    if (validate(input)) {
      input.classList.remove('invalid');
    } else {
      input.classList.add('invalid');
    }
    if (input.parentNode) {
      checkEmptyLine(input.parentNode);
    }
  }
  checkInput();

  input.addEventListener('keyup', checkInput);
  input.addEventListener('focus', function() {
    selectLine(input.parentNode);
  });

  input.addEventListener('blur', function() {
    if (validate(input)) {
      input.lastValidValue = input.value;
    }
  });

  return input;
}

function checkEmptyLine(line) {
  const inputs = line.querySelectorAll('input');
  let empty = true;
  for (let i = 0; i !== inputs.length; i++) {
    if (inputs[i].value !== '') {
      empty = false;
    }
  }
  if (empty) {
    line.classList.add('empty');
  } else {
    line.classList.remove('empty');
  }
}

function selectLine(line, opt_focusInput) {
  if (line.classList.contains('selected')) {
    return;
  }
  const selected =
      line.parentElement && line.parentElement.querySelector('.selected');
  if (selected) {
    selected.classList.remove('selected');
  }
  line.classList.add('selected');
  if (opt_focusInput) {
    const el = line.querySelector('.preselected');
    if (el) {
      line.firstChild.select();
      line.firstChild.focus();
    }
  }
}

function commitFreshLineIfValid(opt_selectNew) {
  const line = $('config-dialog').querySelector('.config-list-row.fresh');
  if (line.querySelector('.invalid')) {
    return false;
  }
  line.classList.remove('fresh');
  const freshLine = line.parentElement.createRow();
  if (opt_selectNew) {
    freshLine.querySelector('.preselected').focus();
  }
  return true;
}

function populatePortStatus(devicesStatusMap) {
  for (const deviceId in devicesStatusMap) {
    if (!devicesStatusMap.hasOwnProperty(deviceId)) {
      continue;
    }
    const deviceStatus = devicesStatusMap[deviceId];
    const deviceStatusMap = deviceStatus.ports;

    const deviceSection = $(deviceId);
    if (!deviceSection) {
      continue;
    }

    const devicePorts = deviceSection.querySelector('.device-ports');
    if (alreadyDisplayed(devicePorts, deviceStatus)) {
      continue;
    }

    devicePorts.textContent = '';
    for (const port in deviceStatusMap) {
      if (!deviceStatusMap.hasOwnProperty(port)) {
        continue;
      }

      const status = deviceStatusMap[port];
      const portIcon = document.createElement('div');
      portIcon.className = 'port-icon';
      // status === 0 is the default (connected) state.
      if (status === -1 || status === -2) {
        portIcon.classList.add('transient');
        portIcon.title = 'Attempting to forward port';
      } else if (status < 0) {
        portIcon.classList.add('error');
        portIcon.title = 'Port forwarding failed';
      } else {
        portIcon.title = 'Successfully forwarded port';
      }
      devicePorts.appendChild(portIcon);

      const portNumber = document.createElement('div');
      portNumber.className = 'port-number';
      portNumber.textContent = ':' + port;
      devicePorts.appendChild(portNumber);
    }

    function updatePortForwardingInfo(browserSection) {
      const icon = browserSection.querySelector('.used-for-port-forwarding');
      if (icon) {
        icon.hidden = (browserSection.id !== deviceStatus.browserId);
      }
      updateBrowserVisibility(browserSection);
    }

    Array.prototype.forEach.call(
        deviceSection.querySelectorAll('.browser'), updatePortForwardingInfo);

    updateUsernameVisibility(deviceSection);
  }

  function clearBrowserPorts(browserSection) {
    const icon = browserSection.querySelector('.used-for-port-forwarding');
    if (icon) {
      icon.hidden = true;
    }
    updateBrowserVisibility(browserSection);
  }

  function clearPorts(deviceSection) {
    if (deviceSection.id in devicesStatusMap) {
      return;
    }
    const devicePorts = deviceSection.querySelector('.device-ports');
    devicePorts.textContent = '';
    delete devicePorts.cachedJSON;

    Array.prototype.forEach.call(
        deviceSection.querySelectorAll('.browser'), clearBrowserPorts);
  }

  Array.prototype.forEach.call(
      document.querySelectorAll('.device'), clearPorts);
}

// Expose functions on |window| since they are called from C++ by name.
Object.assign(window, {
  updateDiscoverUsbDevicesEnabled,
  updatePortForwardingEnabled,
  updatePortForwardingConfig,
  updateTCPDiscoveryEnabled,
  updateTCPDiscoveryConfig,
  updateBubbleLockingCheckbox,
  populateNativeUITargets,
  populateTargets,
  populatePortStatus,
  showIncognitoWarning,
  showNativeUILaunchButton,
  setHostVersion,
});

document.addEventListener('DOMContentLoaded', onload);
window.addEventListener('hashchange', onHashChange);
