/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * Check that tab descriptor survives after the page navigates and changes
 * process.
 */

const EXAMPLE_COM_URI =
  "http://example.com/document-builder.sjs?html=<div id=com>com";
const EXAMPLE_NET_URI =
  "http://example.net/document-builder.sjs?html=<div id=net>net";

add_task(async function() {
  const tab = await addTab(EXAMPLE_COM_URI);
  const toolbox = await gDevTools.showToolboxForTab(tab);
  const target = toolbox.target;
  const client = toolbox.commands.client;

  info("Retrieve the initial list of tab descriptors");
  const tabDescriptors = await client.mainRoot.listTabs();
  const tabDescriptor = tabDescriptors.find(
    d => decodeURIComponent(d.url) === EXAMPLE_COM_URI
  );
  ok(tabDescriptor, "Should have a descriptor actor for the tab");

  info("Retrieve the target corresponding to the TabDescriptor");
  const comTabTarget = await tabDescriptor.getTarget();
  is(
    target,
    comTabTarget,
    "The toolbox target is also the target associated with the tab descriptor"
  );

  await navigateTo(EXAMPLE_NET_URI);

  info("Call list tabs again to update the tab descriptor forms");
  await client.mainRoot.listTabs();

  is(
    decodeURIComponent(tabDescriptor.url),
    EXAMPLE_NET_URI,
    "The existing descriptor now points to the new URI"
  );

  const newTarget = toolbox.target;

  const serverSideTargetSwitchingEnabled = Services.prefs.getBoolPref(
    "devtools.target-switching.server.enabled"
  );
  if (isFissionEnabled() || serverSideTargetSwitchingEnabled) {
    is(
      comTabTarget.actorID,
      null,
      "With Fission or server side target switching, example.com target front is destroyed"
    );
    ok(
      comTabTarget != newTarget,
      "With Fission or server side target switching, a new target was created for example.net"
    );
  } else {
    is(
      comTabTarget,
      newTarget,
      "Without Fission, nor server side targets, the example.com target is reused"
    );
  }

  const onDescriptorDestroyed = tabDescriptor.once("descriptor-destroyed");

  await removeTab(tab);

  info("Wait for descriptor destroyed event");
  await onDescriptorDestroyed;
  ok(tabDescriptor.isDestroyed(), "the descriptor front is really destroyed");
});
