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

(async function(/** @type {import('test_runner').TestRunner} */ testRunner) {
  await testRunner.startBlank(`Test creating hidden target`);

  const existingTargets = new Set();

  function testRunnerLog() {
    testRunner.log(
        arguments[0] ?? '', arguments[1] ?? '', testRunner.stabilizeNames,
        ['sessionId', 'targetId']);
  }

  const {result: targets} = await testRunner.browserP().Target.getTargets();
  for (const target of targets.targetInfos) {
    existingTargets.add(target.targetId);
  }

  testRunner.browserP().Target.onDetachedFromTarget((event) => {
    testRunnerLog(event, 'DetachedFromTarget');
  });
  testRunner.browserP().Target.onTargetDestroyed((event) => {
    testRunnerLog(event, 'TargetDestroyed');
  });
  /**
   * Filter out the targets that are already present in the existing targets set
   * keeping only the new targets. If the result is an error, return the error.
   */
  function filterTargets(result) {
    if (result.error) {
      return result.error;
    }
    return result.result.targetInfos
        .filter(item => !existingTargets.has(item.targetId))
        .map(item => ({targetId: item.targetId, url: item.url}));
  }

  const target = testRunner.browserP().Target;
  await target.setDiscoverTargets({discover: true});
  await target.setAutoAttach(
      {autoAttach: true, waitForDebuggerOnStart: true, flatten: true});
  const response = await target.attachToBrowserTarget();

  // Create a new session and create a hidden target via it.
  const newBrowserSession =
      new TestRunner.Session(testRunner, response.result.sessionId);

  testRunnerLog('Create hidden target');
  const {result: hiddenTarget} =
      await newBrowserSession.protocol.Target.createTarget({
        url: 'about:blank?HIDDEN=TARGET',
        hidden: true,
      });

  target.attachToTarget({targetId: hiddenTarget.targetId, flatten: true});
  const attachedToHiddenTargetEvent = await target.onceAttachedToTarget();
  testRunnerLog('Attached to the hidden target');

  const hiddenSession = new TestRunner.Session(
      testRunner, attachedToHiddenTargetEvent.params.sessionId);

  // Verify the hidden target's session is available.
  testRunnerLog(
      filterTargets(await hiddenSession.protocol.Target.getTargets()),
      `Filtered targets via hidden target's session: `);
  // Verify the hidden target is visible from the browser session.
  testRunnerLog(
      filterTargets(await testRunner.browserP().Target.getTargets()),
      `Filtered targets via browser session: `);

  testRunnerLog('Disconnect the parent session');
  newBrowserSession.disconnect();

  await testRunner.browserP().Target.onceTargetDestroyed();

  // Verify the hidden target's session is closed.
  testRunnerLog(
      filterTargets(await hiddenSession.protocol.Target.getTargets()),
      `Expected error response: `);

  // Verify the hidden target is not present anymore.
  testRunnerLog(
      filterTargets(await testRunner.browserP().Target.getTargets()),
      `Filtered targets via browser session: `);

  testRunner.completeTest();
});
