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

import * as Platform from '../../core/platform/platform.js';
import * as Root from '../../core/root/root.js';
import * as SDK from '../../core/sdk/sdk.js';
import type * as Protocol from '../../generated/protocol.js';
import {createTarget} from '../../testing/EnvironmentHelpers.js';
import {describeWithMockConnection} from '../../testing/MockConnection.js';
import {MockProtocolBackend} from '../../testing/MockScopeChain.js';
import {encodeSourceMap, waitForAllSourceMapsProcessed} from '../../testing/SourceMapEncoder.js';
import {protocolCallFrame, stringifyFrame} from '../../testing/StackTraceHelpers.js';
import * as ScopesCodec from '../../third_party/source-map-scopes-codec/source-map-scopes-codec.js';
import * as TextUtils from '../text_utils/text_utils.js';
import * as Workspace from '../workspace/workspace.js';

import * as Bindings from './bindings.js';

const {urlString} = Platform.DevToolsPath;

describeWithMockConnection('CompilerScriptMapping', () => {
  let backend: MockProtocolBackend;
  let debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding;
  let workspace: Workspace.Workspace.WorkspaceImpl;

  beforeEach(() => {
    const targetManager = SDK.TargetManager.TargetManager.instance();
    workspace = Workspace.Workspace.WorkspaceImpl.instance({forceNew: true});
    const resourceMapping = new Bindings.ResourceMapping.ResourceMapping(targetManager, workspace);
    const ignoreListManager = Workspace.IgnoreListManager.IgnoreListManager.instance({forceNew: true});
    debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance({
      forceNew: true,
      resourceMapping,
      targetManager,
      ignoreListManager,
      workspace,
    });
    backend = new MockProtocolBackend();
  });

  afterEach(async () => {
    await waitForAllSourceMapsProcessed();
  });

  const waitForUISourceCodeAdded =
      (url: string, target: SDK.Target.Target): Promise<Workspace.UISourceCode.UISourceCode> =>
          debuggerWorkspaceBinding.waitForUISourceCodeAdded(urlString`${url}`, target);
  const waitForUISourceCodeRemoved = (uiSourceCode: Workspace.UISourceCode.UISourceCode): Promise<void> =>
      new Promise(resolve => {
        const {eventType, listener} =
            workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeRemoved, event => {
              if (event.data === uiSourceCode) {
                workspace.removeEventListener(eventType, listener);
                resolve();
              }
            });
      });

  it('creates UISourceCodes with the correct content type', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const sources = ['foo.js', 'bar.ts', 'baz.jsx'];
    const scriptInfo = {url: `${sourceRoot}/bundle.js`, content: '1;\n'};
    const sourceMapInfo = {url: `${scriptInfo.url}.map`, content: {version: 3, mappings: '', sourceRoot, sources}};

    await Promise.all([
      ...sources.map(name => waitForUISourceCodeAdded(`${sourceRoot}/${name}`, target).then(uiSourceCode => {
        assert.isTrue(uiSourceCode.contentType().isFromSourceMap());
        assert.isTrue(uiSourceCode.contentType().isScript());
      })),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);
  });

  it('removes webpack hashes from display names', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const sources = ['foo.js?a1b2', 'two%20words.ts?c3d4', '?e5f6'];
    const scriptInfo = {url: `${sourceRoot}/bundle.js`, content: '1;\n'};
    const sourceMapInfo = {url: `${scriptInfo.url}.map`, content: {version: 3, mappings: '', sourceRoot, sources}};

    const namesPromise = Promise.all(
        sources.map(
            name =>
                waitForUISourceCodeAdded(`${sourceRoot}/${name}`, target).then(uiSourceCode => uiSourceCode.name())),
    );
    await backend.addScript(target, scriptInfo, sourceMapInfo);

    assert.deepEqual(await namesPromise, ['foo.js', 'two words.ts', '?e5f6']);
  });

  it('creates UISourceCodes with the correct media type', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/bundle.js`,
      content: 'foo();\nbar();\nbaz();\n',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(['0:0 => foo.js:0:0', '1:0 => bar.ts:0:0', '2:0 => baz.jsx:0:0'], sourceRoot),
    };

    const [fooUISourceCode, barUISourceCode, bazUISourceCode] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/foo.js`, target),
      waitForUISourceCodeAdded(`${sourceRoot}/bar.ts`, target),
      waitForUISourceCodeAdded(`${sourceRoot}/baz.jsx`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    assert.strictEqual(fooUISourceCode.mimeType(), 'text/javascript');
    assert.strictEqual(barUISourceCode.mimeType(), 'text/typescript');
    assert.strictEqual(bazUISourceCode.mimeType(), 'text/jsx');
  });

  it('creates UISourceCodes with the correct content and metadata', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const sourceContent = 'const x = 1; console.log(x)';
    const scriptInfo = {
      url: `${sourceRoot}/script.min.js`,
      content: 'console.log(1);',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: {version: 1, mappings: '', sources: ['script.js'], sourcesContent: [sourceContent], sourceRoot},
    };
    const [uiSourceCode] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    const metadata = await uiSourceCode.requestMetadata();
    assert.strictEqual(metadata?.contentSize, sourceContent.length);

    const content = await uiSourceCode.requestContentData();
    assert.instanceOf(content, TextUtils.ContentData.ContentData);
    assert.strictEqual(content.text, sourceContent);
  });

  it('creates separate UISourceCodes for separate targets', async () => {
    // Create a main target and a worker child target.
    const mainTarget = createTarget({
      id: 'main' as Protocol.Target.TargetID,
      type: SDK.Target.Type.FRAME,
    });
    const workerTarget = createTarget({
      id: 'worker' as Protocol.Target.TargetID,
      type: SDK.Target.Type.ServiceWorker,
      parentTarget: mainTarget,
    });

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/script.min.js`,
      content: 'console.log(1);',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(['0:0 => script.js:0:0'], sourceRoot),
    };

    // Register the same script for both targets, and wait until the `CompilerScriptMapping`
    // adds a UISourceCode for the `script.js` that is listed in the source map for each of
    // the two targets.
    const [mainUISourceCode, mainScript, workerUISourceCode, workerScript] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, mainTarget),
      backend.addScript(mainTarget, scriptInfo, sourceMapInfo),
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, workerTarget),
      backend.addScript(workerTarget, scriptInfo, sourceMapInfo),
    ]);

    assert.notStrictEqual(mainUISourceCode, workerUISourceCode);
    for (const {script, uiSourceCode} of
             [{script: mainScript, uiSourceCode: mainUISourceCode},
              {script: workerScript, uiSourceCode: workerUISourceCode}]) {
      const rawLocations = await debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0);
      assert.lengthOf(rawLocations, 1);
      const [rawLocation] = rawLocations;
      assert.strictEqual(rawLocation.script(), script);
      const uiLocation = await debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
      assert.strictEqual(uiLocation!.uiSourceCode, uiSourceCode);
    }
  });

  it('creates separate UISourceCodes for content scripts', async () => {
    // By default content scripts are ignore listed, which will prevent processing the
    // source map. We need to disable that option.
    Workspace.IgnoreListManager.IgnoreListManager.instance().unIgnoreListContentScripts();

    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/script.min.js`,
      content: 'console.log(1);',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(['0:0 => script.js:0:0'], sourceRoot),
    };

    // Register `script.min.js` as regular script first.
    const regularScriptInfo = {...scriptInfo, isContentScript: false};
    const [regularUISourceCode, regularScript] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, target),
      backend.addScript(target, regularScriptInfo, sourceMapInfo),
    ]);

    // Now register the same `script.min.js` as content script.
    const contentScriptInfo = {...scriptInfo, isContentScript: true};
    const [contentUISourceCode, contentScript] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, target),
      backend.addScript(target, contentScriptInfo, sourceMapInfo),
    ]);

    assert.notStrictEqual(regularUISourceCode, contentUISourceCode);
    for (const {script, uiSourceCode} of
             [{script: regularScript, uiSourceCode: regularUISourceCode},
              {script: contentScript, uiSourceCode: contentUISourceCode}]) {
      const rawLocations = await debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 0, 0);
      assert.lengthOf(rawLocations, 1);
      const [rawLocation] = rawLocations;
      assert.strictEqual(rawLocation.script(), script);
      const uiLocation = await debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
      assert.strictEqual(uiLocation!.uiSourceCode, uiSourceCode);
    }
  });

  it('correctly marks known 3rdparty UISourceCodes', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/bundle.js`,
      content: '1;\n',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: {
        version: 3,
        mappings: '',
        sourceRoot,
        sources: ['app.ts', 'lib.ts'],
        ignoreList: [1],
      },
    };

    await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/app.ts`, target).then(uiSourceCode => {
        assert.isFalse(uiSourceCode.isKnownThirdParty(), '`app.ts` is not a known 3rdparty script');
      }),
      waitForUISourceCodeAdded(`${sourceRoot}/lib.ts`, target).then(uiSourceCode => {
        assert.isTrue(uiSourceCode.isKnownThirdParty(), '`lib.ts` is a known 3rdparty script');
      }),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);
  });

  it('correctly maps to inline <script>s with `//# sourceURL` annotations', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/test.out.js`,
      content: 'function f(x) {\n  console.log(x);\n}\n',
      startLine: 4,
      startOffset: 12,
      hasSourceURL: true,
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(
          [
            '0:0 => test.ts:0:0',
            '1:0 => test.ts:1:0',
            '1:2 => test.ts:1:2',
            '2:0 => test.ts:2:0',
          ],
          sourceRoot),
    };

    const [uiSourceCode, script] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/test.ts`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    const rawLocations = await debuggerWorkspaceBinding.uiLocationToRawLocations(uiSourceCode, 1, 2);
    assert.lengthOf(rawLocations, 1);
    const [rawLocation] = rawLocations;
    assert.strictEqual(rawLocation.script(), script);
    assert.strictEqual(rawLocation.lineNumber, 1);
    assert.strictEqual(rawLocation.columnNumber, 2);
    const uiLocation = await debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
    assert.strictEqual(uiLocation!.uiSourceCode, uiSourceCode);
    assert.strictEqual(uiLocation!.lineNumber, 1);
    assert.strictEqual(uiLocation!.columnNumber, 2);
  });

  it('correctly removes UISourceCodes when detaching a sourcemap', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/test.out.js`,
      content: '1\n2\n',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(
          [
            '0:0 => a.ts:0:0',
            '1:0 => b.ts:1:0',
          ],
          sourceRoot),
    };

    const [, , script] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/a.ts`, target),
      waitForUISourceCodeAdded(`${sourceRoot}/b.ts`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    script.debuggerModel.sourceMapManager().detachSourceMap(script);

    assert.isNull(
        workspace.uiSourceCodeForURL(urlString`${`${sourceRoot}/a.ts`}`), '`a.ts` should not be around anymore');
    assert.isNull(
        workspace.uiSourceCodeForURL(urlString`${`${sourceRoot}/b.ts`}`), '`b.ts` should not be around anymore');
  });

  it('correctly reports source-mapped lines', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const scriptInfo = {
      url: `${sourceRoot}/test.out.js`,
      content: 'function f(x) {\n  console.log(x);\n}\n',
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: encodeSourceMap(
          [
            '0:9 => test.ts:0:1',
            '1:0 => test.ts:4:0',
            '1:2 => test.ts:4:2',
            '2:0 => test.ts:2:0',
          ],
          sourceRoot),
    };

    const [uiSourceCode] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/test.ts`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    const mappedLines = await debuggerWorkspaceBinding.getMappedLines(uiSourceCode);
    assert.deepEqual(mappedLines, new Set([0, 2, 4]));
  });

  describe('supports modern Web development workflows', () => {
    it('supports webpack code splitting', async () => {
      // This is basically the "Shared code with webpack entry point code-splitting" scenario
      // outlined in http://go/devtools-source-identities, where two routes (`route1.ts` and
      // `route2.ts`) share some common code (`shared.ts`), and webpack is configured to spit
      // out a dedicated bundle for each route (`route1.js` and `route2.js`). The demo can be
      // found at https://devtools-source-identities.glitch.me/webpack-code-split/ for further
      // reference.
      const target = createTarget();
      const sourceRoot = 'webpack:///src';

      // Load the script and source map for the first route.
      const route1ScriptInfo = {
        url: 'http://example.com/route1.js',
        content: 'function f(x){}\nf(1)',
      };
      const route1SourceMapInfo = {
        url: `${route1ScriptInfo.url}.map`,
        content: encodeSourceMap(['0:0 => shared.ts:0:0', '1:0 => route1.ts:0:0'], sourceRoot),
      };
      const [route1UISourceCode, firstSharedUISourceCode, route1Script] = await Promise.all([
        waitForUISourceCodeAdded(`${sourceRoot}/route1.ts`, target),
        waitForUISourceCodeAdded(`${sourceRoot}/shared.ts`, target),
        backend.addScript(target, route1ScriptInfo, route1SourceMapInfo),
      ]);

      // Both `route1.ts` and `shared.ts` are referred to only by `route1.js` at this point.
      assert.deepEqual(await debuggerWorkspaceBinding.uiLocationToRawLocations(route1UISourceCode, 0), [
        route1Script.debuggerModel.createRawLocation(route1Script, 1, 0),
      ]);
      assert.deepEqual(await debuggerWorkspaceBinding.uiLocationToRawLocations(firstSharedUISourceCode, 0), [
        route1Script.debuggerModel.createRawLocation(route1Script, 0, 0),
      ]);

      // Load the script and source map for the second route. At this point a new `shared.ts` should
      // appear, replacing the original `shared.ts` UISourceCode.
      const route2ScriptInfo = {
        url: 'http://example.com/route2.js',
        content: 'function f(x){}\nf(2)',
      };
      const route2SourceMapInfo = {
        url: `${route2ScriptInfo.url}.map`,
        content: encodeSourceMap(['0:0 => shared.ts:0:0', '1:0 => route2.ts:0:0'], sourceRoot),
      };
      const [route2UISourceCode, secondSharedUISourceCode, route2Script] = await Promise.all([
        waitForUISourceCodeAdded(`${sourceRoot}/route2.ts`, target),
        waitForUISourceCodeAdded(`${sourceRoot}/shared.ts`, target),
        backend.addScript(target, route2ScriptInfo, route2SourceMapInfo),
        waitForUISourceCodeRemoved(firstSharedUISourceCode),
      ]);

      // Now `route1.ts` is provided exclusively by `route1.js`...
      const route1UILocation = route1UISourceCode.uiLocation(0, 0);
      const route1Locations = await debuggerWorkspaceBinding.uiLocationToRawLocations(
          route1UILocation.uiSourceCode, route1UILocation.lineNumber, route1UILocation.columnNumber);
      assert.lengthOf(route1Locations, 1);
      const [route1Location] = route1Locations;
      assert.strictEqual(route1Location.script(), route1Script);
      assert.deepEqual(await debuggerWorkspaceBinding.rawLocationToUILocation(route1Location), route1UILocation);

      // ...and `route2.ts` is provided exclusively by `route2.js`...
      const route2UILocation = route2UISourceCode.uiLocation(0, 0);
      const route2Locations = await debuggerWorkspaceBinding.uiLocationToRawLocations(
          route2UILocation.uiSourceCode, route2UILocation.lineNumber, route2UILocation.columnNumber);
      assert.lengthOf(route2Locations, 1);
      const [route2Location] = route2Locations;
      assert.strictEqual(route2Location.script(), route2Script);
      assert.deepEqual(await debuggerWorkspaceBinding.rawLocationToUILocation(route2Location), route2UILocation);

      // ...but `shared.ts` is provided by both `route1.js` and `route2.js`.
      const sharedUILocation = secondSharedUISourceCode.uiLocation(0, 0);
      const sharedLocations = await debuggerWorkspaceBinding.uiLocationToRawLocations(
          sharedUILocation.uiSourceCode, sharedUILocation.lineNumber, sharedUILocation.columnNumber);
      assert.sameMembers(sharedLocations.map(location => location.script()), [route1Script, route2Script]);
      for (const location of sharedLocations) {
        assert.deepEqual(await debuggerWorkspaceBinding.rawLocationToUILocation(location), sharedUILocation);
      }
    });

    it('supports webpack hot module replacement', async () => {
      // This simulates the webpack HMR machinery, where originally a `bundle.js` is served,
      // which includes embedded authored code for `lib.js` and `app.js`, both of which map
      // to `bundle.js`. Later an update script is sent that replaces `app.js` with a newer
      // version, while sending the same authored code for `lib.js` (presumably because the
      // devserver figured the file might have changed). Now the initial `app.js` should be
      // removed and `bundle.js` will have un-mapped locations for the `app.js` part. The
      // new `app.js` will point to the update script. `lib.js` remains unchanged.
      //
      // This is a generalization of https://crbug.com/1403362 and http://crbug.com/1403432,
      // which both present special cases of the general stale mapping problem.
      const target = createTarget();
      const sourceRoot = 'webpack:///src';

      // Load the original bundle.
      const originalScriptInfo = {
        url: 'http://example.com/bundle.js',
        content: 'const f = console.log;\nf("Hello from the original bundle");',
      };
      const originalSourceMapInfo = {
        url: `${originalScriptInfo.url}.map`,
        content: encodeSourceMap(
            [
              '0:0 => lib.js:0:0',
              'lib.js: const f = console.log;',
              '1:0 => app.js:0:0',
              'app.js: f("Hello from the original bundle")',
            ],
            sourceRoot),
      };
      const [originalLibUISourceCode, originalAppUISourceCode, originalScript] = await Promise.all([
        waitForUISourceCodeAdded(`${sourceRoot}/lib.js`, target),
        waitForUISourceCodeAdded(`${sourceRoot}/app.js`, target),
        backend.addScript(target, originalScriptInfo, originalSourceMapInfo),
      ]);

      // Initially the original `bundle.js` maps to the original `app.js` and `lib.js`.
      assert.deepEqual(
          await debuggerWorkspaceBinding.rawLocationToUILocation(
              originalScript.debuggerModel.createRawLocation(originalScript, 0, 0)),
          originalLibUISourceCode.uiLocation(0, 0));
      assert.deepEqual(
          await debuggerWorkspaceBinding.rawLocationToUILocation(
              originalScript.debuggerModel.createRawLocation(originalScript, 1, 0)),
          originalAppUISourceCode.uiLocation(0, 0));

      // Inject the HMR update script.
      const updateScriptInfo = {
        url: 'http://example.com/hot.update.1234.js',
        content: 'f("Hello from the update");',
      };
      const updateSourceMapInfo = {
        url: `${updateScriptInfo.url}.map`,
        content: encodeSourceMap(
            [
              '0:0 => app.js:0:0',
              'lib.js: const f = console.log;',
              'app.js: f("Hello from the update")',
            ],
            sourceRoot),
      };
      const [updateAppUISourceCode, , updateScript] = await Promise.all([
        waitForUISourceCodeAdded(`${sourceRoot}/app.js`, target),
        // The original `app.js` should disappear as part of the HMR update.
        waitForUISourceCodeRemoved(originalAppUISourceCode),
        backend.addScript(target, updateScriptInfo, updateSourceMapInfo),
      ]);

      // Now we have a new `app.js`...
      assert.notStrictEqual(updateAppUISourceCode, originalAppUISourceCode);
      assert.isEmpty(await debuggerWorkspaceBinding.uiLocationToRawLocations(originalAppUISourceCode, 0, 0));
      assert.deepEqual(await debuggerWorkspaceBinding.uiLocationToRawLocations(updateAppUISourceCode, 0, 0), [
        updateScript.debuggerModel.createRawLocation(updateScript, 0, 0),
      ]);

      // ...and the `app.js` mapping of the `bundle.js` is now gone...
      const {uiSourceCode} = (await debuggerWorkspaceBinding.rawLocationToUILocation(
          originalScript.debuggerModel.createRawLocation(originalScript, 1, 0)))!;
      assert.notStrictEqual(uiSourceCode, originalAppUISourceCode);
      assert.notStrictEqual(uiSourceCode, updateAppUISourceCode);

      // ...while the `lib.js` mapping of `bundle.js` is still intact (because it
      // was the same content).
      assert.deepEqual(
          await debuggerWorkspaceBinding.rawLocationToUILocation(
              originalScript.debuggerModel.createRawLocation(originalScript, 0, 0)),
          originalLibUISourceCode.uiLocation(0, 0));
    });
  });

  it('assumes UTF-8 encoding for source files embedded in source maps', async () => {
    const target = createTarget();

    const sourceRoot = 'http://example.com';
    const sourceContent = 'console.log("Ahoj světe!");';
    const scriptInfo = {
      url: `${sourceRoot}/script.min.js`,
      content: sourceContent,
    };
    const sourceMapInfo = {
      url: `${scriptInfo.url}.map`,
      content: {version: 3, mappings: '', sources: ['script.js'], sourcesContent: [sourceContent], sourceRoot},
    };
    const [uiSourceCode] = await Promise.all([
      waitForUISourceCodeAdded(`${sourceRoot}/script.js`, target),
      backend.addScript(target, scriptInfo, sourceMapInfo),
    ]);

    const metadata = await uiSourceCode.requestMetadata();
    assert.notStrictEqual(metadata?.contentSize, sourceContent.length);
    const sourceUTF8 = new TextEncoder().encode(sourceContent);
    assert.strictEqual(metadata?.contentSize, sourceUTF8.length);
  });

  describe('translateRawFramesStep', () => {
    it('returns false for builtin frames', async () => {
      const target = createTarget();
      const compilerScriptMapping = new Bindings.CompilerScriptMapping.CompilerScriptMapping(
          target.model(SDK.DebuggerModel.DebuggerModel)!, workspace, debuggerWorkspaceBinding);

      assert.isFalse(await compilerScriptMapping.translateRawFramesStep(
          [{lineNumber: -1, columnNumber: -1, functionName: 'Array.map'}], []));
    });

    it('translates a single frame using "proposal scopes" information', async () => {
      Root.Runtime.experiments.enableForTest(Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES);

      const target = createTarget();
      const compilerScriptMapping = new Bindings.CompilerScriptMapping.CompilerScriptMapping(
          target.model(SDK.DebuggerModel.DebuggerModel)!, workspace, debuggerWorkspaceBinding);
      const sourceMap = encodeSourceMap([
        '0:0 => index.ts:0:0',
        '0:21 => index.ts:2:11',
      ]);
      ScopesCodec.encode(
          new ScopesCodec.ScopeInfoBuilder()
              .startScope(1, 0, {isStackFrame: true, name: 'foo', key: 'fn'})
              .endScope(3, 1)
              .startRange(0, 10, {isStackFrame: true, scopeKey: 'fn'})
              .endRange(0, 23)
              .build(),
          sourceMap as ScopesCodec.SourceMapJson);

      const uiSourceCodePromise = waitForUISourceCodeAdded('http://example.com/index.ts', target);
      const script =
          await backend.addScript(target, {url: 'http://example.com/index.js', content: 'function f(){debugger;}'}, {
            url: 'http://example.com/index.js.map',
            content: sourceMap,
          });

      const translatedFrames:
          Parameters<Bindings.CompilerScriptMapping.CompilerScriptMapping['translateRawFramesStep']>[1] = [];
      assert.isTrue(await compilerScriptMapping.translateRawFramesStep(
          [{
            scriptId: script.scriptId,
            url: script.sourceURL,
            lineNumber: 0,
            columnNumber: 21,
            functionName: 'f',
          }],
          translatedFrames));
      assert.deepEqual(translatedFrames, [[{
                         line: 2,
                         column: 11,
                         name: 'foo',
                         uiSourceCode: await uiSourceCodePromise,
                         url: undefined,
                       }]]);

      Root.Runtime.experiments.disableForTest(Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES);
    });

    it('translates a single frame using "fallback" scope information (created from AST and mappigns)', async () => {
      const target = createTarget();
      const compilerScriptMapping = new Bindings.CompilerScriptMapping.CompilerScriptMapping(
          target.model(SDK.DebuggerModel.DebuggerModel)!, workspace, debuggerWorkspaceBinding);
      const sourceMap = encodeSourceMap([
        '0:0 => index.ts:0:0',
        '0:10 => index.ts:1:10@foo',
        '0:21 => index.ts:2:11',
      ]);

      const uiSourceCodePromise = waitForUISourceCodeAdded('http://example.com/index.ts', target);
      const script =
          await backend.addScript(target, {url: 'http://example.com/index.js', content: 'function f(){debugger;}'}, {
            url: 'http://example.com/index.js.map',
            content: sourceMap,
          });

      const translatedFrames:
          Parameters<Bindings.CompilerScriptMapping.CompilerScriptMapping['translateRawFramesStep']>[1] = [];
      assert.isTrue(await compilerScriptMapping.translateRawFramesStep(
          [{
            scriptId: script.scriptId,
            url: script.sourceURL,
            lineNumber: 0,
            columnNumber: 21,
            functionName: 'f',
          }],
          translatedFrames));
      assert.deepEqual(translatedFrames, [[{
                         line: 2,
                         column: 11,
                         name: 'foo',
                         uiSourceCode: await uiSourceCodePromise,
                         url: undefined,
                       }]]);
    });

    it('expands inlined frames and populates UISourceCode', async () => {
      Root.Runtime.experiments.enableForTest(Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES);

      const target = createTarget();
      const compilerScriptMapping = new Bindings.CompilerScriptMapping.CompilerScriptMapping(
          target.model(SDK.DebuggerModel.DebuggerModel)!, workspace, debuggerWorkspaceBinding);
      //
      //    orig. code                         gen. code
      //             10        20                       10        20
      //    012345678901234567890              012345678901234567890
      //
      // 0: function inner() {                 print('hello')
      // 1:   print('hello');
      // 2: }
      // 3:
      // 4: function outer() {
      // 5:   if (true) {
      // 6:     inner();
      // 7:   }
      // 8: }
      // 9:
      // 10: outer();

      const builder = new ScopesCodec.ScopeInfoBuilder();
      builder.startScope(0, 0, {kind: 'global', key: 'global'})
          .startScope(0, 14, {kind: 'function', name: 'inner', key: 'inner', isStackFrame: true})
          .endScope(2, 1)
          .startScope(4, 14, {kind: 'function', name: 'outer', key: 'outer', isStackFrame: true})
          .startScope(5, 12, {kind: 'block', key: 'block'})
          .endScope(7, 3)
          .endScope(8, 1)
          .endScope(11, 0);

      builder.startRange(0, 0, {scopeKey: 'global'})
          .startRange(0, 0, {scopeKey: 'outer', callSite: {sourceIndex: 0, line: 10, column: 5}})
          .startRange(0, 0, {scopeKey: 'block'})
          .startRange(0, 0, {scopeKey: 'inner', callSite: {sourceIndex: 0, line: 6, column: 9}})
          .endRange(0, 14)
          .endRange(0, 14)
          .endRange(0, 14)
          .endRange(1, 0);

      const sourceMap =
          ScopesCodec.encode(builder.build(), encodeSourceMap(['0:5 => index.ts:1:7']) as ScopesCodec.SourceMapJson);
      const script =
          await backend.addScript(target, {url: 'http://example.com/index.js', content: 'print(\'hello\')'}, {
            url: 'http://example.com/index.js.map',
            content: sourceMap as SDK.SourceMap.SourceMapV3,
          });

      const translatedFrames:
          Parameters<Bindings.CompilerScriptMapping.CompilerScriptMapping['translateRawFramesStep']>[1] = [];
      assert.isTrue(await compilerScriptMapping.translateRawFramesStep(
          [protocolCallFrame(`${script.sourceURL}:${script.scriptId}::0:5`)], translatedFrames));

      assert.deepEqual(translatedFrames[0].map(stringifyFrame), [
        'at inner (index.ts:1:7)',
        'at outer (index.ts:6:9)',
        'at <anonymous> (index.ts:10:5)',
      ]);

      const uiSourceCode = compilerScriptMapping.uiSourceCodeForURL(urlString`http://example.com/index.ts`, false);
      assert.exists(uiSourceCode);
      assert.strictEqual(translatedFrames[0][0].uiSourceCode, uiSourceCode);
      assert.strictEqual(translatedFrames[0][1].uiSourceCode, uiSourceCode);
      assert.strictEqual(translatedFrames[0][2].uiSourceCode, uiSourceCode);

      Root.Runtime.experiments.disableForTest(Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES);
    });
  });
});
