// Copyright 2026 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 'chai';

import {describe, type InspectedPage, it, setup} from '../../../test/api/mocha-interface.js';
import * as Platform from '../../core/platform/platform.js';
import * as SDK from '../../core/sdk/sdk.js';
import * as Formatter from '../../models/formatter/formatter.js';
import {encodeSourceMap} from '../../testing/SourceMapEncoder.js';
import * as ScopesCodec from '../../third_party/source-map-scopes-codec/source-map-scopes-codec.js';

import * as SourceMapScopes from './source_map_scopes.js';

function createSourceMapUrl(builder: ScopesCodec.ScopeInfoBuilder, textMap: string[] = []): string {
  const baseMap = textMap.length > 0 ? encodeSourceMap(textMap) : {
    version: 3,
    sources: ['index.ts'],
    mappings: '',
  };
  const map = ScopesCodec.encode(builder.build(), baseMap as ScopesCodec.SourceMapJson);
  const json = JSON.stringify(map);
  return `data:application/json;charset=utf-8;base64,${Platform.StringUtilities.toBase64(json)}`;
}

async function setupScriptAndPause(
    inspectedPage: InspectedPage,
    debuggerModel: SDK.DebuggerModel.DebuggerModel,
    code: string,
    builder: ScopesCodec.ScopeInfoBuilder,
    textMap: string[] = [],
    ): Promise<{callFrame: SDK.DebuggerModel.CallFrame, sourceMap: SDK.SourceMap.SourceMap}> {
  const sourceMapUrl = createSourceMapUrl(builder, textMap);
  const scriptContent = `${code}\n//# sourceURL=test.js\n//# sourceMappingURL=${sourceMapUrl}`;
  const pausedPromise = debuggerModel.once(SDK.DebuggerModel.Events.DebuggerPaused);

  await inspectedPage.evaluate((src: string) => {
    const script = document.createElement('script');
    script.textContent = src;
    document.body.appendChild(script);
  }, scriptContent);

  void inspectedPage.evaluate(() => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    setTimeout((window as any).runTest, 0);
  });
  await pausedPromise;

  const callFrames = debuggerModel.debuggerPausedDetails()?.callFrames;
  assert.isDefined(callFrames, 'Expected callFrames to exist');
  assert.isNotEmpty(callFrames, 'Expected callFrames not to be empty');
  const callFrame = callFrames[0];
  const sourceMap = await debuggerModel.sourceMapManager().sourceMapForClientPromise(callFrame.script);
  assert.isDefined(sourceMap, 'Expected source map to attach');
  return {callFrame, sourceMap};
}

function formatRemoteObject(value?: SDK.RemoteObject.RemoteObject): string {
  if (!value) {
    return '<unavailable>';
  }
  if (value.type === 'undefined') {
    return 'undefined';
  }
  if (value.type === 'object' && value.subtype !== 'null') {
    return `<${value.className ?? value.description ?? 'object'}>`;
  }
  return JSON.stringify(value.value);
}

async function stringifyScopeChain(scopeChain: SDK.DebuggerModel.ScopeChainEntry[]): Promise<string> {
  const lines: string[] = [];
  for (const scope of scopeChain) {
    const title = scope.name() ? `${scope.typeName()} (${scope.name()})` : scope.typeName();
    if (scope.type() === 'global' && !(scope instanceof SDK.SourceMapScopeChainEntry.SourceMapScopeChainEntry)) {
      lines.push(`${title} (<global>)`);
      continue;
    }
    lines.push(title);
    for (const extra of scope.extraProperties()) {
      lines.push(`  [${extra.name}]: ${formatRemoteObject(extra.value)}`);
    }
    const {properties} = await scope.object().getAllProperties(false, false);
    for (const prop of properties ?? []) {
      lines.push(`  ${prop.name}: ${formatRemoteObject(prop.value)}`);
    }
  }
  return lines.join('\n');
}

describe('NamesResolver API Test', () => {
  setup({
    creationOptions: {
      hostConfig: {
        devToolsSourceMapScopesInSourcesPanel: {
          enabled: true,
        },
      },
    },
  });

  it('builds function, block, and global scopes with mapped variable values', async ({inspectedPage, universe}) => {
    const primaryTarget = universe.targetManager.primaryPageTarget();
    assert.isNotNull(primaryTarget);

    const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
    assert.isNotNull(debuggerModel);

    await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

    const builder = new ScopesCodec.ScopeInfoBuilder();
    builder.startSource();
    builder.startScope(0, 0, {kind: 'global', variables: ['authoredGlobalVar'], key: 'global'});
    builder.startScope(
        0, 0, {kind: 'function', name: 'testLocalAndBlock', isStackFrame: true, variables: ['outerVar'], key: 'fn'});
    builder.startScope(2, 2, {kind: 'block', variables: ['innerVar'], key: 'block'});
    builder.endScope(5, 3);
    builder.endScope(6, 1);
    builder.endScope(8, 0);
    builder.endSource();

    builder.startRange(0, 0, {scopeKey: 'global', values: ['"fromAuthoredGlobal"']});
    builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['outerVar']});
    builder.startRange(2, 2, {scopeKey: 'block', values: ['innerVar']});
    builder.endRange(5, 3);
    builder.endRange(6, 1);
    builder.endRange(8, 0);

    const code = [
      'function testLocalAndBlock() {',
      '  const outerVar = 10;',
      '  {',
      '    const innerVar = 20;',
      '    debugger;',
      '  }',
      '}',
      'window.runTest = testLocalAndBlock;',
    ].join('\n');

    const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
    try {
      const scopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

      assert.strictEqual(await stringifyScopeChain(scopeChain), [
        'Block',
        '  innerVar: 20',
        'Local (testLocalAndBlock)',
        '  outerVar: 10',
        'Global',
        '  authoredGlobalVar: "fromAuthoredGlobal"',
        'Global (<global>)',
      ].join('\n'));
    } finally {
      if (debuggerModel.isPaused()) {
        await debuggerModel.resume();
      }
    }
  });

  it('evaluates shadowed variables in parent closure scope using V8 scopeNumber', async ({inspectedPage, universe}) => {
    const primaryTarget = universe.targetManager.primaryPageTarget();
    assert.isNotNull(primaryTarget);

    const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
    assert.isNotNull(debuggerModel);

    await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

    const builder = new ScopesCodec.ScopeInfoBuilder();
    builder.startSource();
    builder.startScope(0, 0, {kind: 'global', key: 'global'});
    builder.startScope(0, 0,
                       {kind: 'function', name: 'testShadowing', isStackFrame: true, variables: ['x'], key: 'outerFn'});
    builder.startScope(3, 2, {kind: 'function', name: 'innerFn', isStackFrame: true, variables: ['x'], key: 'innerFn'});
    builder.endScope(6, 3);
    builder.endScope(8, 1);
    builder.endScope(10, 0);
    builder.endSource();

    builder.startRange(0, 0, {scopeKey: 'global'});
    builder.startRange(0, 0, {scopeKey: 'outerFn', isStackFrame: true, values: ['x']});
    builder.startRange(3, 2, {scopeKey: 'innerFn', isStackFrame: true, values: ['x']});
    builder.endRange(6, 3);
    builder.endRange(8, 1);
    builder.endRange(10, 0);

    const code = [
      'function testShadowing() {',
      '  const x = "outer";',
      '  eval("");',
      '  function innerFn() {',
      '    const x = "inner";',
      '    debugger;',
      '  }',
      '  innerFn();',
      '}',
      'window.runTest = testShadowing;',
    ].join('\n');

    const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
    try {
      const scopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

      assert.strictEqual(await stringifyScopeChain(scopeChain), [
        'Local (innerFn)',
        '  x: "inner"',
        'Closure (testShadowing)',
        '  x: "outer"',
        'Global',
        'Global (<global>)',
      ].join('\n'));
    } finally {
      if (debuggerModel.isPaused()) {
        await debuggerModel.resume();
      }
    }
  });

  it('evaluates multiple nested block scopes with variable shadowing', async ({inspectedPage, universe}) => {
    const primaryTarget = universe.targetManager.primaryPageTarget();
    assert.isNotNull(primaryTarget);

    const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
    assert.isNotNull(debuggerModel);

    await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

    const builder = new ScopesCodec.ScopeInfoBuilder();
    builder.startSource();
    builder.startScope(0, 0, {kind: 'global', key: 'global'});
    builder.startScope(0, 0,
                       {kind: 'function', name: 'testNestedBlocks', isStackFrame: true, variables: ['x'], key: 'fn'});
    builder.startScope(2, 2, {kind: 'block', variables: ['x'], key: 'outerBlock'});
    builder.startScope(4, 4, {kind: 'block', variables: ['x'], key: 'innerBlock'});
    builder.endScope(7, 5);
    builder.endScope(8, 3);
    builder.endScope(9, 1);
    builder.endScope(11, 0);
    builder.endSource();

    builder.startRange(0, 0, {scopeKey: 'global'});
    builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['x']});
    builder.startRange(2, 2, {scopeKey: 'outerBlock', values: ['x']});
    builder.startRange(4, 4, {scopeKey: 'innerBlock', values: ['x']});
    builder.endRange(7, 5);
    builder.endRange(8, 3);
    builder.endRange(9, 1);
    builder.endRange(11, 0);

    const code = [
      'function testNestedBlocks() {',
      '  const x = "fn";',
      '  {',
      '    const x = "outerBlock";',
      '    {',
      '      const x = "innerBlock";',
      '      debugger;',
      '    }',
      '  }',
      '}',
      'window.runTest = testNestedBlocks;',
    ].join('\n');

    const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
    try {
      const scopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

      assert.strictEqual(await stringifyScopeChain(scopeChain), [
        'Block',
        '  x: "innerBlock"',
        'Block',
        '  x: "outerBlock"',
        'Local (testNestedBlocks)',
        '  x: "fn"',
        'Global',
        'Global (<global>)',
      ].join('\n'));
    } finally {
      if (debuggerModel.isPaused()) {
        await debuggerModel.resume();
      }
    }
  });

  it('matches multiple nested empty scopes reported by V8 CDP', async ({inspectedPage, universe}) => {
    const primaryTarget = universe.targetManager.primaryPageTarget();
    assert.isNotNull(primaryTarget);

    const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
    assert.isNotNull(debuggerModel);

    await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

    const builder = new ScopesCodec.ScopeInfoBuilder();
    builder.startSource();
    builder.startScope(0, 0, {kind: 'global', key: 'global'});
    builder.startScope(0, 0,
                       {kind: 'function', name: 'testNestedEmpty', isStackFrame: true, variables: ['val'], key: 'fn'});
    builder.startScope(2, 2, {kind: 'block', variables: [], key: 'empty1'});
    builder.startScope(3, 4, {kind: 'block', variables: [], key: 'empty2'});
    builder.endScope(5, 5);
    builder.endScope(6, 3);
    builder.endScope(7, 1);
    builder.endScope(9, 0);
    builder.endSource();

    builder.startRange(0, 0, {scopeKey: 'global'});
    builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['val']});
    builder.startRange(2, 2, {scopeKey: 'empty1', values: []});
    builder.startRange(3, 4, {scopeKey: 'empty2', values: []});
    builder.endRange(5, 5);
    builder.endRange(6, 3);
    builder.endRange(7, 1);
    builder.endRange(9, 0);

    const code = [
      'function testNestedEmpty() {',
      '  const val = 42;',
      '  {',
      '    {',
      '      debugger;',
      '    }',
      '  }',
      '}',
      'window.runTest = testNestedEmpty;',
    ].join('\n');

    const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
    try {
      const scopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

      assert.strictEqual(await stringifyScopeChain(scopeChain), [
        'Block',
        'Block',
        'Local (testNestedEmpty)',
        '  val: 42',
        'Global',
        'Global (<global>)',
      ].join('\n'));
    } finally {
      if (debuggerModel.isPaused()) {
        await debuggerModel.resume();
      }
    }
  });

  it('resolves multi-level inlined functions and caller virtual call frames', async ({inspectedPage, universe}) => {
    const primaryTarget = universe.targetManager.primaryPageTarget();
    assert.isNotNull(primaryTarget);

    const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
    assert.isNotNull(debuggerModel);

    await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

    const builder = new ScopesCodec.ScopeInfoBuilder();
    builder.startSource();
    builder.startScope(0, 0, {kind: 'global', key: 'global'});
    builder.startScope(0, 0,
                       {kind: 'function', name: 'rootCaller', isStackFrame: true, variables: ['rootVar'], key: 'root'});
    builder.startScope(1, 2,
                       {kind: 'function', name: 'inlinedMid', isStackFrame: true, variables: ['midVar'], key: 'mid'});
    builder.startScope(
        2, 2, {kind: 'function', name: 'inlinedLeaf', isStackFrame: true, variables: ['leafVar'], key: 'leaf'});
    builder.endScope(3, 3);
    builder.endScope(4, 3);
    builder.endScope(5, 1);
    builder.endScope(7, 0);
    builder.endSource();

    builder.startRange(0, 0, {scopeKey: 'global'});
    builder.startRange(0, 0, {scopeKey: 'root', isStackFrame: true, values: ['rootVar']});
    builder.startRange(2, 2, {
      scopeKey: 'mid',
      isStackFrame: false,
      callSite: {sourceIndex: 0, line: 1, column: 2},
      values: ['midVar'],
    });
    builder.startRange(3, 2, {
      scopeKey: 'leaf',
      isStackFrame: false,
      callSite: {sourceIndex: 0, line: 2, column: 2},
      values: ['leafVar'],
    });
    builder.endRange(4, 12);
    builder.endRange(4, 12);
    builder.endRange(5, 1);
    builder.endRange(7, 0);

    const code = [
      'function rootCaller() {',
      '  const rootVar = 1;',
      '  const midVar = 2;',
      '  const leafVar = 3;',
      '  debugger;',
      '}',
      'window.runTest = rootCaller;',
    ].join('\n');

    const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
    try {
      const scopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

      assert.strictEqual(await stringifyScopeChain(scopeChain), [
        'Local (inlinedLeaf)',
        '  leafVar: 3',
        'Closure (inlinedMid)',
        '  midVar: 2',
        'Closure (rootCaller)',
        '  rootVar: 1',
        'Global',
        'Global (<global>)',
      ].join('\n'));

      const midFrame = callFrame.createVirtualCallFrame(1, 'inlinedMid');
      const midScopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(midFrame, universe.debuggerWorkspaceBinding);
      assert.strictEqual(await stringifyScopeChain(midScopeChain), [
        'Local (inlinedMid)',
        '  midVar: 2',
        'Closure (rootCaller)',
        '  rootVar: 1',
        'Global',
        'Global (<global>)',
      ].join('\n'));

      const rootFrame = callFrame.createVirtualCallFrame(2, 'rootCaller');
      const rootScopeChain =
          await SourceMapScopes.NamesResolver.resolveScopeChain(rootFrame, universe.debuggerWorkspaceBinding);
      assert.strictEqual(await stringifyScopeChain(rootScopeChain), [
        'Local (rootCaller)',
        '  rootVar: 1',
        'Global',
        'Global (<global>)',
      ].join('\n'));
    } finally {
      if (debuggerModel.isPaused()) {
        await debuggerModel.resume();
      }
    }
  });

  it('distinguishes between variables with actual undefined value and throwing ReferenceError in V8',
     async ({inspectedPage, universe}) => {
       const primaryTarget = universe.targetManager.primaryPageTarget();
       assert.isNotNull(primaryTarget);

       const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
       assert.isNotNull(debuggerModel);

       await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

       const builder = new ScopesCodec.ScopeInfoBuilder();
       builder.startSource();
       builder.startScope(0, 0, {kind: 'global', key: 'global'});
       builder.startScope(0, 0, {
         kind: 'function',
         name: 'testUndefinedAndThrowing',
         isStackFrame: true,
         variables: ['legitUndefined', 'nonExistentVar'],
         key: 'fn',
       });
       builder.endScope(4, 1);
       builder.endScope(6, 0);
       builder.endSource();

       builder.startRange(0, 0, {scopeKey: 'global'});
       builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['legitUndefined', 'nonExistentVar']});
       builder.endRange(4, 1);
       builder.endRange(6, 0);

       const code = [
         'function testUndefinedAndThrowing() {',
         '  const legitUndefined = undefined;',
         '  debugger;',
         '}',
         'window.runTest = testUndefinedAndThrowing;',
       ].join('\n');

       const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
       try {
         const scopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

         assert.strictEqual(await stringifyScopeChain(scopeChain), [
           'Local (testUndefinedAndThrowing)',
           '  legitUndefined: undefined',
           '  nonExistentVar: <unavailable>',
           'Global',
           'Global (<global>)',
         ].join('\n'));
       } finally {
         if (debuggerModel.isPaused()) {
           await debuggerModel.resume();
         }
       }
     });

  it('evaluates binding expressions without variable shadowing when runtime code defines __res',
     async ({inspectedPage, universe}) => {
       const primaryTarget = universe.targetManager.primaryPageTarget();
       assert.isNotNull(primaryTarget);

       const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
       assert.isNotNull(debuggerModel);

       await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

       const builder = new ScopesCodec.ScopeInfoBuilder();
       builder.startSource();
       builder.startScope(0, 0, {kind: 'global', key: 'global'});
       builder.startScope(0, 0, {
         kind: 'function',
         name: 'testNoShadowing',
         isStackFrame: true,
         variables: ['__res', 'computed'],
         key: 'fn',
       });
       builder.endScope(4, 1);
       builder.endScope(6, 0);
       builder.endSource();

       builder.startRange(0, 0, {scopeKey: 'global'});
       builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['__res', 'other']});
       builder.endRange(4, 1);
       builder.endRange(6, 0);

       const code = [
         'function testNoShadowing() {',
         '  const __res = "user_res";',
         '  const other = __res + "_ok";',
         '  debugger;',
         '}',
         'window.runTest = testNoShadowing;',
       ].join('\n');

       const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
       try {
         const scopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

         assert.strictEqual(await stringifyScopeChain(scopeChain), [
           'Local (testNoShadowing)',
           '  __res: "user_res"',
           '  computed: "user_res_ok"',
           'Global',
           'Global (<global>)',
         ].join('\n'));
       } finally {
         if (debuggerModel.isPaused()) {
           await debuggerModel.resume();
         }
       }
     });

  it('drops inner block scopes and populates returnValue extraProperties when paused at V8 return point',
     async ({inspectedPage, universe}) => {
       const primaryTarget = universe.targetManager.primaryPageTarget();
       assert.isNotNull(primaryTarget);

       const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
       assert.isNotNull(debuggerModel);

       await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

       const builder = new ScopesCodec.ScopeInfoBuilder();
       builder.startSource();
       builder.startScope(0, 0, {kind: 'global', key: 'global'});
       builder.startScope(0, 0,
                          {kind: 'function', name: 'testReturn', isStackFrame: true, variables: ['fnVar'], key: 'fn'});
       builder.startScope(2, 2, {kind: 'block', variables: ['blockVar'], key: 'block'});
       builder.endScope(7, 1);
       builder.endScope(7, 1);
       builder.endScope(9, 0);
       builder.endSource();

       builder.startRange(0, 0, {scopeKey: 'global'});
       builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['fnVar']});
       builder.startRange(2, 2, {scopeKey: 'block', values: ['blockVar']});
       builder.endRange(7, 1);
       builder.endRange(7, 1);
       builder.endRange(9, 0);

       const code = [
         'function testReturn() {',
         '  const fnVar = 10;',
         '  {',
         '    const blockVar = 20;',
         '    debugger;',
         '    return fnVar + blockVar;',
         '  }',
         '}',
         'window.runTest = testReturn;',
       ].join('\n');

       const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
       try {
         const initialScopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);
         assert.strictEqual(await stringifyScopeChain(initialScopeChain), [
           'Block',
           '  blockVar: 20',
           'Local (testReturn)',
           '  fnVar: 10',
           'Global',
           'Global (<global>)',
         ].join('\n'));

         // Step until paused at return point (where returnValue is non-null)
         let currentFrame: SDK.DebuggerModel.CallFrame = callFrame;
         while (currentFrame.returnValue() === null) {
           const stepPaused = debuggerModel.once(SDK.DebuggerModel.Events.DebuggerPaused);
           void debuggerModel.stepOver();
           await stepPaused;
           const frames: SDK.DebuggerModel.CallFrame[]|undefined = debuggerModel.debuggerPausedDetails()?.callFrames;
           assert.isDefined(frames);
           assert.isNotEmpty(frames);
           currentFrame = frames[0];
         }

         const returnScopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(currentFrame, universe.debuggerWorkspaceBinding);
         assert.strictEqual(await stringifyScopeChain(returnScopeChain), [
           'Local (testReturn)',
           '  [Return value]: 30',
           '  fnVar: 10',
           'Global',
           'Global (<global>)',
         ].join('\n'));
         assert.isDefined(returnScopeChain[0].extraProperties()[0].syntheticSetter);
       } finally {
         if (debuggerModel.isPaused()) {
           await debuggerModel.resume();
         }
       }
     });

  it('does not evaluate binding expressions in target page when source map has USER provenance',
     async ({inspectedPage, universe}) => {
       const primaryTarget = universe.targetManager.primaryPageTarget();
       assert.isNotNull(primaryTarget);

       const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
       assert.isNotNull(debuggerModel);

       await inspectedPage.goToHtml('<!DOCTYPE html><html><body></body></html>');

       const builder = new ScopesCodec.ScopeInfoBuilder();
       builder.startSource();
       builder.startScope(0, 0, {kind: 'global', key: 'global'});
       builder.startScope(
           0, 0, {kind: 'function', name: 'authoredFn', isStackFrame: true, variables: ['evilVar'], key: 'fn'});
       builder.endScope(3, 1);
       builder.endScope(5, 0);
       builder.endSource();

       builder.startRange(0, 0, {scopeKey: 'global'});
       builder.startRange(0, 0, {scopeKey: 'fn', isStackFrame: true, values: ['(window.evilExecuted = true, 999)']});
       builder.endRange(3, 1);
       builder.endRange(5, 0);

       const code = [
         'function compiledFn() {',
         '  const a = 456;',
         '  debugger;',
         '}',
         'window.runTest = compiledFn;',
       ].join('\n');

       const {callFrame, sourceMap} =
           await setupScriptAndPause(inspectedPage, debuggerModel, code, builder,
                                     ['0:9 => index.ts:0:9@authoredFn', '1:8 => index.ts:1:8@safeMappedVar']);
       try {
         debuggerModel.setSourceMapURL(callFrame.script, sourceMap.url(), SDK.SourceMap.SourceMapProvenance.USER);
         const userSourceMap = await debuggerModel.sourceMapManager().sourceMapForClientPromise(callFrame.script);
         assert.strictEqual(userSourceMap?.provenance(), SDK.SourceMap.SourceMapProvenance.USER);

         const scopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

         assert.strictEqual(await stringifyScopeChain(scopeChain), [
           'Local (compiledFn)',
           '  [this]: <Window>',
           '  safeMappedVar: 456',
           'Global (<global>)',
         ].join('\n'));

         await debuggerModel.resume();
         const evilExecuted =
             await inspectedPage.evaluate(() => Boolean((window as unknown as {evilExecuted?: boolean}).evilExecuted));
         assert.isFalse(evilExecuted, 'Binding expression from USER source map must NOT be evaluated');
       } finally {
         if (debuggerModel.isPaused()) {
           await debuggerModel.resume();
         }
         Formatter.FormatterWorkerPool.FormatterWorkerPool.removeInstance();
       }
     });

  it('resolves scope variables on pages with CSP blocking unsafe-eval and isolates runtime and syntax errors',
     async ({inspectedPage, universe}) => {
       const primaryTarget = universe.targetManager.primaryPageTarget();
       assert.isNotNull(primaryTarget);

       const debuggerModel = primaryTarget.model(SDK.DebuggerModel.DebuggerModel);
       assert.isNotNull(debuggerModel);

       // Page with a strict Content-Security-Policy that allows inline scripts but blocks `eval()` (no 'unsafe-eval').
       await inspectedPage.goToHtml([
         '<!DOCTYPE html>',
         '<html>',
         '<head>',
         '  <meta http-equiv="Content-Security-Policy" content="script-src \'unsafe-inline\'">',
         '</head>',
         '<body></body>',
         '</html>',
       ].join('\n'));

       // First scope (Block): All expressions are valid or throw runtime errors (batched execution succeeds in one call).
       // Also verifies `evalBlocked` is true (confirming `eval()` is blocked by CSP in the page & frame).
       // Second scope (Local): Contains a syntax error ('brokenSyntax)') alongside valid and runtime-throwing expressions
       // (batch fails to parse and falls back to per-variable evaluation without losing valid variables).
       const builder = new ScopesCodec.ScopeInfoBuilder();
       builder.startSource();
       builder.startScope(0, 0, {kind: 'global', key: 'global'});
       builder.startScope(0, 0, {
         kind: 'function',
         name: 'testCspAndErrors',
         isStackFrame: true,
         variables: ['fnValid', 'fnSyntaxError', 'fnRuntimeError', 'fnAfterErrors'],
         key: 'fn',
       });
       builder.startScope(2, 2, {
         kind: 'block',
         variables: ['evalBlocked', 'blockValid', 'blockThrowing', 'blockUndefined'],
         key: 'block',
       });
       builder.endScope(5, 3);
       builder.endScope(6, 1);
       builder.endScope(8, 0);
       builder.endSource();

       builder.startRange(0, 0, {scopeKey: 'global'});
       builder.startRange(0, 0, {
         scopeKey: 'fn',
         isStackFrame: true,
         values: ['a + 1', 'brokenSyntax)', 'nonExistentFnVar.prop', 'b * 2'],
       });
       builder.startRange(2, 2, {
         scopeKey: 'block',
         values: ['evalBlocked', 'a', '(() => { throw new Error("boom"); })()', 'undefVal'],
       });
       builder.endRange(5, 3);
       builder.endRange(6, 1);
       builder.endRange(8, 0);

       const code = [
         'function testCspAndErrors() {',
         '  const a = 10, b = 20, undefVal = undefined;',
         '  {',
         '    let evalBlocked = false; try { eval("1 + 1"); } catch (e) { evalBlocked = e instanceof EvalError; }',
         '    debugger;',
         '  }',
         '}',
         'window.runTest = testCspAndErrors;',
       ].join('\n');

       const {callFrame} = await setupScriptAndPause(inspectedPage, debuggerModel, code, builder);
       try {
         const scopeChain =
             await SourceMapScopes.NamesResolver.resolveScopeChain(callFrame, universe.debuggerWorkspaceBinding);

         assert.strictEqual(await stringifyScopeChain(scopeChain), [
           'Block',
           '  evalBlocked: true',
           '  blockValid: 10',
           '  blockThrowing: <unavailable>',
           '  blockUndefined: undefined',
           'Local (testCspAndErrors)',
           '  fnValid: 11',
           '  fnSyntaxError: <unavailable>',
           '  fnRuntimeError: <unavailable>',
           '  fnAfterErrors: 40',
           'Global',
           'Global (<global>)',
         ].join('\n'));
       } finally {
         if (debuggerModel.isPaused()) {
           await debuggerModel.resume();
         }
       }
     });
});
