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

(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');
}

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) {
  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 ? '' :
                              'Pending authentication: please accept ' +
            'debugging session on the device.';

    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 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);
