/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import type * as PublicAPI from '../../../extension-api/ExtensionAPI'; // eslint-disable-line rulesdir/es_modules_import
import type * as Platform from '../../core/platform/platform.js';
import type * as HAR from '../har/har.js';

/* eslint-disable @typescript-eslint/naming-convention,@typescript-eslint/no-non-null-assertion */
export namespace PrivateAPI {
  export namespace Panels {
    export const enum SearchAction {
      CancelSearch = 'cancelSearch',
      PerformSearch = 'performSearch',
      NextSearchResult = 'nextSearchResult',
      PreviousSearchResult = 'previousSearchResult',
    }
  }

  export const enum Events {
    ButtonClicked = 'button-clicked-',
    PanelObjectSelected = 'panel-objectSelected-',
    InspectedURLChanged = 'inspected-url-changed',
    NetworkRequestFinished = 'network-request-finished',
    OpenResource = 'open-resource',
    PanelSearch = 'panel-search-',
    ResourceAdded = 'resource-added',
    ResourceContentCommitted = 'resource-content-committed',
    ViewShown = 'view-shown-',
    ViewHidden = 'view-hidden,',
    ThemeChange = 'host-theme-change',
  }

  export const enum Commands {
    AddRequestHeaders = 'addRequestHeaders',
    ApplyStyleSheet = 'applyStyleSheet',
    CreatePanel = 'createPanel',
    CreateSidebarPane = 'createSidebarPane',
    CreateToolbarButton = 'createToolbarButton',
    EvaluateOnInspectedPage = 'evaluateOnInspectedPage',
    ForwardKeyboardEvent = '_forwardKeyboardEvent',
    GetHAR = 'getHAR',
    GetPageResources = 'getPageResources',
    GetRequestContent = 'getRequestContent',
    GetResourceContent = 'getResourceContent',
    OpenResource = 'openResource',
    Reload = 'Reload',
    Subscribe = 'subscribe',
    SetOpenResourceHandler = 'setOpenResourceHandler',
    SetThemeChangeHandler = 'setThemeChangeHandler',
    SetResourceContent = 'setResourceContent',
    SetSidebarContent = 'setSidebarContent',
    SetSidebarHeight = 'setSidebarHeight',
    SetSidebarPage = 'setSidebarPage',
    ShowPanel = 'showPanel',
    Unsubscribe = 'unsubscribe',
    UpdateButton = 'updateButton',
    RegisterLanguageExtensionPlugin = 'registerLanguageExtensionPlugin',
    GetWasmLinearMemory = 'getWasmLinearMemory',
    GetWasmLocal = 'getWasmLocal',
    GetWasmGlobal = 'getWasmGlobal',
    GetWasmOp = 'getWasmOp',
    RegisterRecorderExtensionPlugin = 'registerRecorderExtensionPlugin',
    CreateRecorderView = 'createRecorderView',
    ShowRecorderView = 'showRecorderView',
  }

  export const enum LanguageExtensionPluginCommands {
    AddRawModule = 'addRawModule',
    RemoveRawModule = 'removeRawModule',
    SourceLocationToRawLocation = 'sourceLocationToRawLocation',
    RawLocationToSourceLocation = 'rawLocationToSourceLocation',
    GetScopeInfo = 'getScopeInfo',
    ListVariablesInScope = 'listVariablesInScope',
    GetTypeInfo = 'getTypeInfo',
    GetFormatter = 'getFormatter',
    GetInspectableAddress = 'getInspectableAddress',
    GetFunctionInfo = 'getFunctionInfo',
    GetInlinedFunctionRanges = 'getInlinedFunctionRanges',
    GetInlinedCalleesRanges = 'getInlinedCalleesRanges',
    GetMappedLines = 'getMappedLines',
    FormatValue = 'formatValue',
    GetProperties = 'getProperties',
    ReleaseObject = 'releaseObject',
  }

  export const enum LanguageExtensionPluginEvents {
    UnregisteredLanguageExtensionPlugin = 'unregisteredLanguageExtensionPlugin',
  }

  export const enum RecorderExtensionPluginCommands {
    Stringify = 'stringify',
    StringifyStep = 'stringifyStep',
    Replay = 'replay',
  }

  export const enum RecorderExtensionPluginEvents {
    UnregisteredRecorderExtensionPlugin = 'unregisteredRecorderExtensionPlugin',
  }

  export interface EvaluateOptions {
    frameURL?: string;
    useContentScriptContext?: boolean;
    scriptExecutionContext?: string;
  }

  type RegisterLanguageExtensionPluginRequest = {
    command: Commands.RegisterLanguageExtensionPlugin,
    pluginName: string,
    port: MessagePort,
    supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes,
  };
  export type RecordingExtensionPluginCapability = 'export'|'replay';
  type RegisterRecorderExtensionPluginRequest = {
    command: Commands.RegisterRecorderExtensionPlugin,
    pluginName: string,
    mediaType?: string, capabilities: RecordingExtensionPluginCapability[], port: MessagePort,
  };
  type CreateRecorderViewRequest = {
    command: Commands.CreateRecorderView,
    id: string,
    title: string,
    pagePath: string,
  };
  type ShowRecorderViewRequest = {
    command: Commands.ShowRecorderView,
    id: string,
  };
  type SubscribeRequest = {command: Commands.Subscribe, type: string};
  type UnsubscribeRequest = {command: Commands.Unsubscribe, type: string};
  type AddRequestHeadersRequest = {
    command: Commands.AddRequestHeaders,
    extensionId: string,
    headers: {[key: string]: string},
  };
  type ApplyStyleSheetRequest = {command: Commands.ApplyStyleSheet, styleSheet: string};
  type CreatePanelRequest = {command: Commands.CreatePanel, id: string, title: string, page: string};
  type ShowPanelRequest = {command: Commands.ShowPanel, id: string};
  type CreateToolbarButtonRequest = {
    command: Commands.CreateToolbarButton,
    id: string,
    icon: string,
    panel: string,
    tooltip?: string,
    disabled?: boolean,
  };
  type UpdateButtonRequest =
      {command: Commands.UpdateButton, id: string, icon?: string, tooltip?: string, disabled?: boolean};
  type CreateSidebarPaneRequest = {command: Commands.CreateSidebarPane, id: string, panel: string, title: string};
  type SetSidebarHeightRequest = {command: Commands.SetSidebarHeight, id: string, height: string};
  type SetSidebarContentRequest = {
    command: Commands.SetSidebarContent,
    id: string,
    evaluateOnPage?: boolean, expression: string,
    rootTitle?: string,
    evaluateOptions?: EvaluateOptions,
  };
  type SetSidebarPageRequest = {command: Commands.SetSidebarPage, id: string, page: string};
  type OpenResourceRequest =
      {command: Commands.OpenResource, url: Platform.DevToolsPath.UrlString, lineNumber: number, columnNumber: number};
  type SetOpenResourceHandlerRequest = {command: Commands.SetOpenResourceHandler, handlerPresent: boolean};
  type SetThemeChangeHandlerRequest = {command: Commands.SetThemeChangeHandler, handlerPresent: boolean};
  type ReloadRequest = {
    command: Commands.Reload,
    options: null|{
      userAgent?: string,
      injectedScript?: string,
      ignoreCache?: boolean,
    },
  };
  type EvaluateOnInspectedPageRequest = {
    command: Commands.EvaluateOnInspectedPage,
    expression: string,
    evaluateOptions?: EvaluateOptions,
  };
  type GetRequestContentRequest = {command: Commands.GetRequestContent, id: number};
  type GetResourceContentRequest = {command: Commands.GetResourceContent, url: string};
  type SetResourceContentRequest =
      {command: Commands.SetResourceContent, url: string, content: string, commit: boolean};
  type ForwardKeyboardEventRequest = {
    command: Commands.ForwardKeyboardEvent,
    entries: Array<KeyboardEventInit&{eventType: string}>,
  };
  type GetHARRequest = {command: Commands.GetHAR};
  type GetPageResourcesRequest = {command: Commands.GetPageResources};
  type GetWasmLinearMemoryRequest = {
    command: Commands.GetWasmLinearMemory,
    offset: number,
    length: number,
    stopId: unknown,
  };
  type GetWasmLocalRequest = {
    command: Commands.GetWasmLocal,
    local: number,
    stopId: unknown,
  };
  type GetWasmGlobalRequest = {
    command: Commands.GetWasmGlobal,
    global: number,
    stopId: unknown,
  };
  type GetWasmOpRequest = {command: Commands.GetWasmOp, op: number, stopId: unknown};

  export type ServerRequests = ShowRecorderViewRequest|CreateRecorderViewRequest|RegisterRecorderExtensionPluginRequest|
      RegisterLanguageExtensionPluginRequest|SubscribeRequest|UnsubscribeRequest|AddRequestHeadersRequest|
      ApplyStyleSheetRequest|CreatePanelRequest|ShowPanelRequest|CreateToolbarButtonRequest|UpdateButtonRequest|
      CreateSidebarPaneRequest|SetSidebarHeightRequest|SetSidebarContentRequest|SetSidebarPageRequest|
      OpenResourceRequest|SetOpenResourceHandlerRequest|SetThemeChangeHandlerRequest|ReloadRequest|
      EvaluateOnInspectedPageRequest|GetRequestContentRequest|GetResourceContentRequest|SetResourceContentRequest|
      ForwardKeyboardEventRequest|GetHARRequest|GetPageResourcesRequest|GetWasmLinearMemoryRequest|GetWasmLocalRequest|
      GetWasmGlobalRequest|GetWasmOpRequest;
  export type ExtensionServerRequestMessage = PrivateAPI.ServerRequests&{requestId?: number};

  type AddRawModuleRequest = {
    method: LanguageExtensionPluginCommands.AddRawModule,
    parameters: {rawModuleId: string, symbolsURL: string|undefined, rawModule: PublicAPI.Chrome.DevTools.RawModule},
  };
  type SourceLocationToRawLocationRequest = {
    method: LanguageExtensionPluginCommands.SourceLocationToRawLocation,
    parameters: {sourceLocation: PublicAPI.Chrome.DevTools.SourceLocation},
  };
  type RawLocationToSourceLocationRequest = {
    method: LanguageExtensionPluginCommands.RawLocationToSourceLocation,
    parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
  };
  type GetScopeInfoRequest = {method: LanguageExtensionPluginCommands.GetScopeInfo, parameters: {type: string}};
  type ListVariablesInScopeRequest = {
    method: LanguageExtensionPluginCommands.ListVariablesInScope,
    parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
  };
  type RemoveRawModuleRequest = {
    method: LanguageExtensionPluginCommands.RemoveRawModule,
    parameters: {rawModuleId: string},
  };
  type GetFunctionInfoRequest = {
    method: LanguageExtensionPluginCommands.GetFunctionInfo,
    parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
  };
  type GetInlinedFunctionRangesRequest = {
    method: LanguageExtensionPluginCommands.GetInlinedFunctionRanges,
    parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
  };
  type GetInlinedCalleesRangesRequest = {
    method: LanguageExtensionPluginCommands.GetInlinedCalleesRanges,
    parameters: {rawLocation: PublicAPI.Chrome.DevTools.RawLocation},
  };
  type GetMappedLinesRequest = {
    method: LanguageExtensionPluginCommands.GetMappedLines,
    parameters: {rawModuleId: string, sourceFileURL: string},
  };
  type FormatValueRequest = {
    method: LanguageExtensionPluginCommands.FormatValue,
    parameters: {expression: string, context: PublicAPI.Chrome.DevTools.RawLocation, stopId: number},
  };
  type GetPropertiesRequest = {
    method: LanguageExtensionPluginCommands.GetProperties,
    parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
  };
  type ReleaseObjectRequest = {
    method: LanguageExtensionPluginCommands.ReleaseObject,
    parameters: {objectId: PublicAPI.Chrome.DevTools.RemoteObjectId},
  };

  export type LanguageExtensionRequests =
      AddRawModuleRequest|SourceLocationToRawLocationRequest|RawLocationToSourceLocationRequest|GetScopeInfoRequest|
      ListVariablesInScopeRequest|RemoveRawModuleRequest|GetFunctionInfoRequest|GetInlinedFunctionRangesRequest|
      GetInlinedCalleesRangesRequest|GetMappedLinesRequest|FormatValueRequest|GetPropertiesRequest|ReleaseObjectRequest;

  type StringifyRequest = {
    method: RecorderExtensionPluginCommands.Stringify,
    parameters: {recording: Record<string, unknown>},
  };

  type StringifyStepRequest = {
    method: RecorderExtensionPluginCommands.StringifyStep,
    parameters: {step: Record<string, unknown>},
  };

  type ReplayRequest = {
    method: RecorderExtensionPluginCommands.Replay,
    parameters: {recording: Record<string, unknown>},
  };

  export type RecorderExtensionRequests = StringifyRequest|StringifyStepRequest|ReplayRequest;
}

declare global {
  interface Window {
    injectedExtensionAPI:
        (extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
         testHook:
             (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
         injectedScriptId: number, targetWindow?: Window) => void;
    buildExtensionAPIInjectedScript(
        extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
        testHook: undefined|((extensionServer: unknown, extensionAPI: unknown) => unknown)): string;
    chrome: PublicAPI.Chrome.DevTools.Chrome;
    webInspector?: APIImpl.InspectorExtensionAPI;
  }
}

export type ExtensionDescriptor = {
  startPage: string,
  name: string,
  exposeExperimentalAPIs: boolean,
  exposeWebInspectorNamespace?: boolean,
  allowFileAccess?: boolean,
};

namespace APIImpl {
  export interface InspectorExtensionAPI {
    languageServices: PublicAPI.Chrome.DevTools.LanguageExtensions;
    recorder: PublicAPI.Chrome.DevTools.RecorderExtensions;
    network: PublicAPI.Chrome.DevTools.Network;
    panels: PublicAPI.Chrome.DevTools.Panels;
    inspectedWindow: PublicAPI.Chrome.DevTools.InspectedWindow;
  }

  export interface ExtensionServerClient {
    _callbacks: {[key: string]: (response: unknown) => unknown};
    _handlers: {[key: string]: (request: {arguments: unknown[]}) => unknown};
    _lastRequestId: number;
    _lastObjectId: number;
    _port: MessagePort;

    _onCallback(request: unknown): void;
    _onMessage(event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void;
    _registerCallback(callback: (response: unknown) => unknown): number;
    registerHandler(command: string, handler: (request: {arguments: unknown[]}) => unknown): void;
    unregisterHandler(command: string): void;
    hasHandler(command: string): boolean;
    sendRequest<ResponseT>(
        request: PrivateAPI.ServerRequests, callback?: ((response: ResponseT) => unknown), transfers?: unknown[]): void;
    nextObjectId(): string;
  }

  export type Callable = (...args: any[]) => void;

  export interface EventSink<ListenerT extends Callable> extends PublicAPI.Chrome.DevTools.EventSink<ListenerT> {
    _type: string;
    _listeners: ListenerT[];
    _customDispatch: undefined|((this: EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown);

    _fire(..._vararg: Parameters<ListenerT>): void;
    _dispatch(request: {arguments: unknown[]}): void;
  }

  export interface Network extends PublicAPI.Chrome.DevTools.Network {
    addRequestHeaders(headers: {[key: string]: string}): void;
  }

  export interface Request extends PublicAPI.Chrome.DevTools.Request, HAR.Log.EntryDTO {
    _id: number;
  }

  export interface Panels extends PublicAPI.Chrome.DevTools.Panels {
    get SearchAction(): {[key: string]: string};
    applyStyleSheet(styleSheet: string): void;
    setOpenResourceHandler(callback?: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown):
        void;
    setThemeChangeHandler(callback?: (themeName: string) => unknown): void;
  }

  export interface ExtensionView extends PublicAPI.Chrome.DevTools.ExtensionView {
    _id: string|null;
  }

  export interface ExtensionSidebarPane extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionSidebarPane {
    setExpression(
        expression: string, rootTitle?: string, evaluteOptions?: PrivateAPI.EvaluateOptions,
        callback?: () => unknown): void;
  }

  export interface PanelWithSidebar extends ExtensionView, PublicAPI.Chrome.DevTools.PanelWithSidebar {
    _hostPanelName: string;
  }

  export interface LanguageExtensions extends PublicAPI.Chrome.DevTools.LanguageExtensions {
    _plugins: Map<PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, MessagePort>;
  }

  export interface RecorderExtensions extends PublicAPI.Chrome.DevTools.RecorderExtensions {
    _plugins: Map<PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, MessagePort>;
  }

  export interface ExtensionPanel extends ExtensionView, PublicAPI.Chrome.DevTools.ExtensionPanel {
    show(): void;
  }

  export interface RecorderView extends ExtensionView, PublicAPI.Chrome.DevTools.RecorderView {}

  export interface Button extends PublicAPI.Chrome.DevTools.Button {
    _id: string;
  }

  export type ResourceData = {url: string, type: string};
  export interface Resource extends PublicAPI.Chrome.DevTools.Resource {
    _type: string;
    _url: string;

    get type(): string;
  }
}

self.injectedExtensionAPI = function(
    extensionInfo: ExtensionDescriptor, inspectedTabId: string, themeName: string, keysToForward: number[],
    testHook: (extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown,
    injectedScriptId: number, targetWindowForTest?: Window): void {
  const keysToForwardSet = new Set<number>(keysToForward);
  const chrome = window.chrome || {};

  const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
  if (devtools_descriptor) {
    return;
  }
  let userAction = false;
  let userRecorderAction = false;

  // Here and below, all constructors are private to API implementation.
  // For a public type Foo, if internal fields are present, these are on
  // a private FooImpl type, an instance of FooImpl is used in a closure
  // by Foo consutrctor to re-bind publicly exported members to an instance
  // of Foo.

  function EventSinkImpl<ListenerT extends APIImpl.Callable>(
      this: APIImpl.EventSink<ListenerT>, type: string,
      customDispatch?: (this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}) => unknown): void {
    this._type = type;
    this._listeners = [];
    this._customDispatch = customDispatch;
  }

  EventSinkImpl.prototype = {
    addListener: function<ListenerT extends APIImpl.Callable>(this: APIImpl.EventSink<ListenerT>, callback: ListenerT):
        void {
          if (typeof callback !== 'function') {
            throw 'addListener: callback is not a function';
          }
          if (this._listeners.length === 0) {
            extensionServer.sendRequest({command: PrivateAPI.Commands.Subscribe, type: this._type});
          }
          this._listeners.push(callback);
          extensionServer.registerHandler('notify-' + this._type, this._dispatch.bind(this));
        },

    removeListener: function<ListenerT extends APIImpl.Callable>(
        this: APIImpl.EventSink<ListenerT>, callback: ListenerT): void {
      const listeners = this._listeners;

      for (let i = 0; i < listeners.length; ++i) {
        if (listeners[i] === callback) {
          listeners.splice(i, 1);
          break;
        }
      }
      if (this._listeners.length === 0) {
        extensionServer.sendRequest({command: PrivateAPI.Commands.Unsubscribe, type: this._type});
      }
    },

    _fire: function<ListenerT extends APIImpl.Callable>(
        this: APIImpl.EventSink<ListenerT>, ..._vararg: Parameters<ListenerT>): void {
      const listeners = this._listeners.slice();
      for (let i = 0; i < listeners.length; ++i) {
        listeners[i].apply(null, Array.from(arguments));
      }
    },

    _dispatch: function<ListenerT extends APIImpl.Callable>(
        this: APIImpl.EventSink<ListenerT>, request: {arguments: unknown[]}): void {
      if (this._customDispatch) {
        this._customDispatch.call(this, request);
      } else {
        this._fire.apply(this, request.arguments as Parameters<ListenerT>);
      }
    },
  };

  function Constructor<NewT extends APIImpl.Callable>(ctor: NewT): new (...args: Parameters<NewT>) =>
      ThisParameterType<NewT> {
    return ctor as unknown as new (...args: Parameters<NewT>) => ThisParameterType<NewT>;
  }

  function InspectorExtensionAPI(this: APIImpl.InspectorExtensionAPI): void {
    this.inspectedWindow = new (Constructor(InspectedWindow))();
    this.panels = new (Constructor(Panels))();
    this.network = new (Constructor(Network))();
    this.languageServices = new (Constructor(LanguageServicesAPI))();
    this.recorder = new (Constructor(RecorderServicesAPI))();
    defineDeprecatedProperty(this, 'webInspector', 'resources', 'network');
  }

  function Network(this: APIImpl.Network): void {
    function dispatchRequestEvent(
        this: APIImpl.EventSink<(request: PublicAPI.Chrome.DevTools.Request) => unknown>,
        message: {arguments: unknown[]}): void {
      const request = message.arguments[1] as APIImpl.Request & {__proto__: APIImpl.Request};

      request.__proto__ = new (Constructor(Request))(message.arguments[0] as number);
      this._fire(request);
    }

    this.onRequestFinished =
        new (Constructor(EventSink))(PrivateAPI.Events.NetworkRequestFinished, dispatchRequestEvent);
    defineDeprecatedProperty(this, 'network', 'onFinished', 'onRequestFinished');

    this.onNavigated = new (Constructor(EventSink))(PrivateAPI.Events.InspectedURLChanged);
  }

  (Network.prototype as Pick<APIImpl.Network, 'getHAR'|'addRequestHeaders'>) = {
    getHAR: function(this: PublicAPI.Chrome.DevTools.Network, callback?: (harLog: Object) => unknown): void {
      function callbackWrapper(response: unknown): void {
        const result =
            response as ({entries: Array<HAR.Log.EntryDTO&{__proto__?: APIImpl.Request, _requestId?: number}>});
        const entries = (result && result.entries) || [];
        for (let i = 0; i < entries.length; ++i) {
          entries[i].__proto__ = new (Constructor(Request))(entries[i]._requestId as number);
          delete entries[i]._requestId;
        }
        callback && callback(result as Object);
      }
      extensionServer.sendRequest({command: PrivateAPI.Commands.GetHAR}, callback && callbackWrapper);
    },

    addRequestHeaders: function(headers: {[key: string]: string}): void {
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname});
    },
  };

  function RequestImpl(this: APIImpl.Request, id: number): void {
    this._id = id;
  }

  (RequestImpl.prototype as Pick<APIImpl.Request, 'getContent'>) = {
    getContent: function(this: APIImpl.Request, callback?: (content: string, encoding: string) => unknown): void {
      function callbackWrapper(response: unknown): void {
        const {content, encoding} = response as {content: string, encoding: string};
        callback && callback(content, encoding);
      }
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.GetRequestContent, id: this._id}, callback && callbackWrapper);
    },
  };

  function Panels(this: APIImpl.Panels): void {
    const panels: {[key: string]: ElementsPanel|SourcesPanel} = {
      elements: new ElementsPanel(),
      sources: new SourcesPanel(),
    };

    function panelGetter(name: string): ElementsPanel|SourcesPanel {
      return panels[name];
    }
    for (const panel in panels) {
      Object.defineProperty(this, panel, {get: panelGetter.bind(null, panel), enumerable: true});
    }
    this.applyStyleSheet = function(styleSheet: string): void {
      extensionServer.sendRequest({command: PrivateAPI.Commands.ApplyStyleSheet, styleSheet: styleSheet});
    };
  }

  (Panels.prototype as
   Pick<APIImpl.Panels, 'create'|'setOpenResourceHandler'|'openResource'|'SearchAction'|'setThemeChangeHandler'>) = {
    create: function(
        title: string, icon: string, page: string,
        callback: (panel: PublicAPI.Chrome.DevTools.ExtensionPanel) => unknown): void {
      const id = 'extension-panel-' + extensionServer.nextObjectId();
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.CreatePanel, id, title, page},
          callback && ((): unknown => callback.call(this, new (Constructor(ExtensionPanel))(id))));
    },

    setOpenResourceHandler: function(
        callback: (resource: PublicAPI.Chrome.DevTools.Resource, lineNumber: number) => unknown): void {
      const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.OpenResource);

      function callbackWrapper(message: unknown): void {
        // Allow the panel to show itself when handling the event.
        userAction = true;
        try {
          const {resource, lineNumber} = message as {resource: APIImpl.ResourceData, lineNumber: number};
          if (canAccessResource(resource)) {
            callback.call(null, new (Constructor(Resource))(resource), lineNumber);
          }
        } finally {
          userAction = false;
        }
      }

      if (!callback) {
        extensionServer.unregisterHandler(PrivateAPI.Events.OpenResource);
      } else {
        extensionServer.registerHandler(PrivateAPI.Events.OpenResource, callbackWrapper);
      }

      // Only send command if we either removed an existing handler or added handler and had none before.
      if (hadHandler === !callback) {
        extensionServer.sendRequest(
            {command: PrivateAPI.Commands.SetOpenResourceHandler, 'handlerPresent': Boolean(callback)});
      }
    },

    setThemeChangeHandler: function(callback: (themeName: string) => unknown): void {
      const hadHandler = extensionServer.hasHandler(PrivateAPI.Events.ThemeChange);

      function callbackWrapper(message: unknown): void {
        const {themeName} = message as {themeName: string};
        chrome.devtools.panels.themeName = themeName;
        callback.call(null, themeName);
      }

      if (!callback) {
        extensionServer.unregisterHandler(PrivateAPI.Events.ThemeChange);
      } else {
        extensionServer.registerHandler(PrivateAPI.Events.ThemeChange, callbackWrapper);
      }

      // Only send command if we either removed an existing handler or added handler and had none before.
      if (hadHandler === !callback) {
        extensionServer.sendRequest(
            {command: PrivateAPI.Commands.SetThemeChangeHandler, 'handlerPresent': Boolean(callback)});
      }
    },

    openResource: function(
        url: Platform.DevToolsPath.UrlString, lineNumber: number, columnNumber?: number,
        _callback?: (response: unknown) => unknown): void {
      const callbackArg = extractCallbackArgument(arguments);
      // Handle older API:
      const columnNumberArg = typeof columnNumber === 'number' ? columnNumber : 0;
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.OpenResource, url, lineNumber, columnNumber: columnNumberArg}, callbackArg);
    },

    get SearchAction(): {[key: string]: string} {
      return {
        CancelSearch: PrivateAPI.Panels.SearchAction.CancelSearch,
        PerformSearch: PrivateAPI.Panels.SearchAction.PerformSearch,
        NextSearchResult: PrivateAPI.Panels.SearchAction.NextSearchResult,
        PreviousSearchResult: PrivateAPI.Panels.SearchAction.PreviousSearchResult,
      };
    },
  };

  function ExtensionViewImpl(this: APIImpl.ExtensionView, id: string|null): void {
    this._id = id;

    function dispatchShowEvent(
        this: APIImpl.EventSink<(window?: Window) => unknown>, message: {arguments: unknown[]}): void {
      const frameIndex = message.arguments[0];
      if (typeof frameIndex === 'number') {
        this._fire(window.parent.frames[frameIndex]);
      } else {
        this._fire();
      }
    }

    if (id) {
      this.onShown = new (Constructor(EventSink))(PrivateAPI.Events.ViewShown + id, dispatchShowEvent);

      this.onHidden = new (Constructor(EventSink))(PrivateAPI.Events.ViewHidden + id);
    }
  }

  function PanelWithSidebarImpl(this: APIImpl.PanelWithSidebar, hostPanelName: string): void {
    ExtensionViewImpl.call(this, null);
    this._hostPanelName = hostPanelName;

    this.onSelectionChanged = new (Constructor(EventSink))(PrivateAPI.Events.PanelObjectSelected + hostPanelName);
  }

  (PanelWithSidebarImpl.prototype as Pick<APIImpl.PanelWithSidebar, 'createSidebarPane'>&
   {__proto__: APIImpl.ExtensionView}) = {
    createSidebarPane: function(
        this: APIImpl.PanelWithSidebar, title: string,
        callback?: (pane: PublicAPI.Chrome.DevTools.ExtensionSidebarPane) => unknown): void {
      const id = 'extension-sidebar-' + extensionServer.nextObjectId();
      function callbackWrapper(): void {
        callback && callback(new (Constructor(ExtensionSidebarPane))(id));
      }
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.CreateSidebarPane, panel: this._hostPanelName, id, title},
          callback && callbackWrapper);
    },

    __proto__: ExtensionViewImpl.prototype,
  };

  function RecorderServicesAPIImpl(this: APIImpl.RecorderExtensions): void {
    this._plugins = new Map();
  }

  async function registerRecorderExtensionPluginImpl(
      this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin, pluginName: string,
      mediaType?: string): Promise<void> {
    if (this._plugins.has(plugin)) {
      throw new Error(`Tried to register plugin '${pluginName}' twice`);
    }
    const channel = new MessageChannel();
    const port = channel.port1;
    this._plugins.set(plugin, port);
    port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.RecorderExtensionRequests>): void => {
      const {requestId} = data;
      dispatchMethodCall(data)
          .then(result => port.postMessage({requestId, result}))
          .catch(error => port.postMessage({requestId, error: {message: error.message}}));
    };

    async function dispatchMethodCall(request: PrivateAPI.RecorderExtensionRequests): Promise<unknown> {
      switch (request.method) {
        case PrivateAPI.RecorderExtensionPluginCommands.Stringify:
          return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
              .stringify(request.parameters.recording);
        case PrivateAPI.RecorderExtensionPluginCommands.StringifyStep:
          return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionExportPlugin)
              .stringifyStep(request.parameters.step);
        case PrivateAPI.RecorderExtensionPluginCommands.Replay:
          try {
            userAction = true;
            userRecorderAction = true;
            return (plugin as PublicAPI.Chrome.DevTools.RecorderExtensionReplayPlugin)
                .replay(request.parameters.recording);
          } finally {
            userAction = false;
            userRecorderAction = false;
          }
        default:
          // @ts-expect-error
          throw new Error(`'${request.method}' is not recognized`);
      }
    }

    const capabilities: PrivateAPI.RecordingExtensionPluginCapability[] = [];

    if ('stringify' in plugin && 'stringifyStep' in plugin) {
      capabilities.push('export');
    }

    if ('replay' in plugin) {
      capabilities.push('replay');
    }

    await new Promise<void>(resolve => {
      extensionServer.sendRequest(
          {
            command: PrivateAPI.Commands.RegisterRecorderExtensionPlugin,
            pluginName,
            mediaType,
            capabilities,
            port: channel.port2,
          },
          () => resolve(), [channel.port2]);
    });
  }

  (RecorderServicesAPIImpl.prototype as Pick<
       APIImpl.RecorderExtensions,
       'registerRecorderExtensionPlugin'|'unregisterRecorderExtensionPlugin'|'createView'>) = {
    registerRecorderExtensionPlugin: registerRecorderExtensionPluginImpl,
    unregisterRecorderExtensionPlugin: async function(
        this: APIImpl.RecorderExtensions, plugin: PublicAPI.Chrome.DevTools.RecorderExtensionPlugin): Promise<void> {
      const port = this._plugins.get(plugin);
      if (!port) {
        throw new Error('Tried to unregister a plugin that was not previously registered');
      }
      this._plugins.delete(plugin);
      port.postMessage({event: PrivateAPI.RecorderExtensionPluginEvents.UnregisteredRecorderExtensionPlugin});
      port.close();
    },
    createView: async function(this: APIImpl.RecorderExtensions, title: string, pagePath: string):
        Promise<PublicAPI.Chrome.DevTools.RecorderView> {
          const id = 'recorder-extension-view-' + extensionServer.nextObjectId();
          await new Promise(resolve => {
            extensionServer.sendRequest(
                {command: PrivateAPI.Commands.CreateRecorderView, id, title, pagePath}, resolve);
          });
          return new (Constructor(RecorderView))(id);
        },
  };

  function LanguageServicesAPIImpl(this: APIImpl.LanguageExtensions): void {
    this._plugins = new Map();
  }

  (LanguageServicesAPIImpl.prototype as PublicAPI.Chrome.DevTools.LanguageExtensions) = {
    registerLanguageExtensionPlugin: async function(
        this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin, pluginName: string,
        supportedScriptTypes: PublicAPI.Chrome.DevTools.SupportedScriptTypes): Promise<void> {
      if (this._plugins.has(plugin)) {
        throw new Error(`Tried to register plugin '${pluginName}' twice`);
      }
      const channel = new MessageChannel();
      const port = channel.port1;
      this._plugins.set(plugin, port);
      port.onmessage = ({data}: MessageEvent<{requestId: number}&PrivateAPI.LanguageExtensionRequests>): void => {
        const {requestId} = data;
        console.time(`${requestId}: ${data.method}`);
        dispatchMethodCall(data)
            .then(result => port.postMessage({requestId, result}))
            .catch(error => port.postMessage({requestId, error: {message: error.message}}))
            .finally(() => console.timeEnd(`${requestId}: ${data.method}`));
      };

      function dispatchMethodCall(request: PrivateAPI.LanguageExtensionRequests): Promise<unknown> {
        switch (request.method) {
          case PrivateAPI.LanguageExtensionPluginCommands.AddRawModule:
            return plugin.addRawModule(
                request.parameters.rawModuleId, request.parameters.symbolsURL, request.parameters.rawModule);
          case PrivateAPI.LanguageExtensionPluginCommands.RemoveRawModule:
            return plugin.removeRawModule(request.parameters.rawModuleId);
          case PrivateAPI.LanguageExtensionPluginCommands.SourceLocationToRawLocation:
            return plugin.sourceLocationToRawLocation(request.parameters.sourceLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.RawLocationToSourceLocation:
            return plugin.rawLocationToSourceLocation(request.parameters.rawLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.GetScopeInfo:
            return plugin.getScopeInfo(request.parameters.type);
          case PrivateAPI.LanguageExtensionPluginCommands.ListVariablesInScope:
            return plugin.listVariablesInScope(request.parameters.rawLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.GetFunctionInfo:
            return plugin.getFunctionInfo(request.parameters.rawLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedFunctionRanges:
            return plugin.getInlinedFunctionRanges(request.parameters.rawLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.GetInlinedCalleesRanges:
            return plugin.getInlinedCalleesRanges(request.parameters.rawLocation);
          case PrivateAPI.LanguageExtensionPluginCommands.GetMappedLines:
            if ('getMappedLines' in plugin) {
              return plugin.getMappedLines(request.parameters.rawModuleId, request.parameters.sourceFileURL);
            }
            return Promise.resolve(undefined);
          case PrivateAPI.LanguageExtensionPluginCommands.FormatValue:
            if ('evaluate' in plugin && plugin.evaluate) {
              return plugin.evaluate(
                  request.parameters.expression, request.parameters.context, request.parameters.stopId);
            }
            return Promise.resolve(undefined);
          case PrivateAPI.LanguageExtensionPluginCommands.GetProperties:
            if ('getProperties' in plugin && plugin.getProperties) {
              return plugin.getProperties(request.parameters.objectId);
            }
            if (!('evaluate' in plugin &&
                  plugin.evaluate)) {  // If evalute is defined but the remote objects methods aren't, that's a bug
              return Promise.resolve(undefined);
            }
            break;
          case PrivateAPI.LanguageExtensionPluginCommands.ReleaseObject:
            if ('releaseObject' in plugin && plugin.releaseObject) {
              return plugin.releaseObject(request.parameters.objectId);
            }
            break;
        }
        throw new Error(`Unknown language plugin method ${request.method}`);
      }

      await new Promise<void>(resolve => {
        extensionServer.sendRequest(
            {
              command: PrivateAPI.Commands.RegisterLanguageExtensionPlugin,
              pluginName,
              port: channel.port2,
              supportedScriptTypes,
            },
            () => resolve(), [channel.port2]);
      });
    },

    unregisterLanguageExtensionPlugin: async function(
        this: APIImpl.LanguageExtensions, plugin: PublicAPI.Chrome.DevTools.LanguageExtensionPlugin): Promise<void> {
      const port = this._plugins.get(plugin);
      if (!port) {
        throw new Error('Tried to unregister a plugin that was not previously registered');
      }
      this._plugins.delete(plugin);
      port.postMessage({event: PrivateAPI.LanguageExtensionPluginEvents.UnregisteredLanguageExtensionPlugin});
      port.close();
    },

    getWasmLinearMemory: async function(
        this: APIImpl.LanguageExtensions, offset: number, length: number, stopId: number): Promise<ArrayBuffer> {
      const result = await new Promise(
          resolve => extensionServer.sendRequest(
              {command: PrivateAPI.Commands.GetWasmLinearMemory, offset, length, stopId}, resolve));
      if (Array.isArray(result)) {
        return new Uint8Array(result).buffer;
      }
      return new ArrayBuffer(0);
    },
    getWasmLocal: async function(
        this: APIImpl.LanguageExtensions, local: number, stopId: number): Promise<PublicAPI.Chrome.DevTools.WasmValue> {
      return new Promise(
          resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmLocal, local, stopId}, resolve));
    },
    getWasmGlobal: async function(this: APIImpl.LanguageExtensions, global: number, stopId: number):
        Promise<PublicAPI.Chrome.DevTools.WasmValue> {
          return new Promise(
              resolve =>
                  extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmGlobal, global, stopId}, resolve));
        },
    getWasmOp: async function(this: APIImpl.LanguageExtensions, op: number, stopId: number):
        Promise<PublicAPI.Chrome.DevTools.WasmValue> {
          return new Promise(
              resolve => extensionServer.sendRequest({command: PrivateAPI.Commands.GetWasmOp, op, stopId}, resolve));
        },
  };

  function declareInterfaceClass<ImplT extends APIImpl.Callable>(implConstructor: ImplT): (
      this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>) => void {
    return function(this: ThisParameterType<ImplT>, ...args: Parameters<ImplT>): void {
      const impl = {__proto__: implConstructor.prototype};
      implConstructor.apply(impl, args);
      populateInterfaceClass(this as {[key: string]: unknown}, impl);
    };
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  function defineDeprecatedProperty(object: any, className: string, oldName: string, newName: string): void {
    let warningGiven = false;
    function getter(): unknown {
      if (!warningGiven) {
        console.warn(className + '.' + oldName + ' is deprecated. Use ' + className + '.' + newName + ' instead');
        warningGiven = true;
      }
      return object[newName];
    }
    object.__defineGetter__(oldName, getter);
  }

  function extractCallbackArgument(args: IArguments): ((...args: unknown[]) => unknown)|undefined {
    const lastArgument = args[args.length - 1];
    return typeof lastArgument === 'function' ? lastArgument as (...args: unknown[]) => unknown : undefined;
  }

  const LanguageServicesAPI = declareInterfaceClass(LanguageServicesAPIImpl);
  const RecorderServicesAPI = declareInterfaceClass(RecorderServicesAPIImpl);
  const Button = declareInterfaceClass(ButtonImpl);
  const EventSink = declareInterfaceClass(EventSinkImpl);
  const ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
  const RecorderView = declareInterfaceClass(RecorderViewImpl);
  const ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
  const PanelWithSidebarClass = declareInterfaceClass(PanelWithSidebarImpl);
  const Request = declareInterfaceClass(RequestImpl);
  const Resource = declareInterfaceClass(ResourceImpl);

  class ElementsPanel extends (Constructor(PanelWithSidebarClass)) {
    constructor() {
      super('elements');
    }
  }

  class SourcesPanel extends (Constructor(PanelWithSidebarClass)) {
    constructor() {
      super('sources');
    }
  }

  function ExtensionPanelImpl(this: APIImpl.ExtensionPanel, id: string): void {
    ExtensionViewImpl.call(this, id);

    this.onSearch = new (Constructor(EventSink))(PrivateAPI.Events.PanelSearch + id);
  }

  (ExtensionPanelImpl.prototype as Pick<APIImpl.ExtensionPanel, 'createStatusBarButton'|'show'>&
   {__proto__: APIImpl.ExtensionView}) = {
    createStatusBarButton: function(
                               this: APIImpl.ExtensionPanel, iconPath: string, tooltipText: string, disabled: boolean):
                               PublicAPI.Chrome.DevTools.Button {
                                 const id = 'button-' + extensionServer.nextObjectId();
                                 extensionServer.sendRequest({
                                   command: PrivateAPI.Commands.CreateToolbarButton,
                                   panel: this._id as string,
                                   id: id,
                                   icon: iconPath,
                                   tooltip: tooltipText,
                                   disabled: Boolean(disabled),
                                 });

                                 return new (Constructor(Button))(id);
                               },

    show: function(this: APIImpl.ExtensionPanel): void {
      if (!userAction) {
        return;
      }

      extensionServer.sendRequest({command: PrivateAPI.Commands.ShowPanel, id: this._id as string});
    },

    __proto__: ExtensionViewImpl.prototype,
  };

  function RecorderViewImpl(this: APIImpl.RecorderView, id: string): void {
    ExtensionViewImpl.call(this, id);
  }

  (RecorderViewImpl.prototype as Pick<APIImpl.RecorderView, 'show'>& {__proto__: APIImpl.ExtensionView}) = {
    show: function(this: APIImpl.RecorderView): void {
      if (!userAction || !userRecorderAction) {
        return;
      }

      extensionServer.sendRequest({command: PrivateAPI.Commands.ShowRecorderView, id: this._id as string});
    },

    __proto__: ExtensionViewImpl.prototype,
  };

  function ExtensionSidebarPaneImpl(this: APIImpl.ExtensionSidebarPane, id: string): void {
    ExtensionViewImpl.call(this, id);
  }

  (ExtensionSidebarPaneImpl.prototype as
       Pick<APIImpl.ExtensionSidebarPane, 'setHeight'|'setExpression'|'setObject'|'setPage'>&
   {__proto__: APIImpl.ExtensionView}) = {
    setHeight: function(this: APIImpl.ExtensionSidebarPane, height: string): void {
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.SetSidebarHeight, id: this._id as string, height: height});
    },

    setExpression: function(
        this: APIImpl.ExtensionSidebarPane, expression: string, rootTitle: string,
        evaluateOptions?: PrivateAPI.EvaluateOptions, _callback?: () => unknown): void {
      extensionServer.sendRequest(
          {
            command: PrivateAPI.Commands.SetSidebarContent,
            id: this._id as string,
            expression: expression,
            rootTitle: rootTitle,
            evaluateOnPage: true,
            evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : {}),
          },
          extractCallbackArgument(arguments));
    },

    setObject: function(
        this: APIImpl.ExtensionSidebarPane, jsonObject: string, rootTitle?: string, callback?: () => unknown): void {
      extensionServer.sendRequest(
          {
            command: PrivateAPI.Commands.SetSidebarContent,
            id: this._id as string,
            expression: jsonObject,
            rootTitle: rootTitle,
          },
          callback);
    },

    setPage: function(this: APIImpl.ExtensionSidebarPane, page: string): void {
      extensionServer.sendRequest({command: PrivateAPI.Commands.SetSidebarPage, id: this._id as string, page: page});
    },

    __proto__: ExtensionViewImpl.prototype,
  };

  function ButtonImpl(this: APIImpl.Button, id: string): void {
    this._id = id;

    this.onClicked = new (Constructor(EventSink))(PrivateAPI.Events.ButtonClicked + id);
  }

  (ButtonImpl.prototype as Pick<APIImpl.Button, 'update'>) = {
    update: function(this: APIImpl.Button, iconPath?: string, tooltipText?: string, disabled?: boolean): void {
      extensionServer.sendRequest({
        command: PrivateAPI.Commands.UpdateButton,
        id: this._id,
        icon: iconPath,
        tooltip: tooltipText,
        disabled: Boolean(disabled),
      });
    },
  };

  function canAccessResource(resource: APIImpl.ResourceData): boolean {
    try {
      return extensionInfo.allowFileAccess || (new URL(resource.url)).protocol !== 'file:';
    } catch (e) {
      return false;
    }
  }

  function InspectedWindow(this: PublicAPI.Chrome.DevTools.InspectedWindow): void {
    function dispatchResourceEvent(
        this: APIImpl.EventSink<(resource: APIImpl.Resource) => unknown>, message: {arguments: unknown[]}): void {
      const resourceData = message.arguments[0] as APIImpl.ResourceData;
      if (!canAccessResource(resourceData)) {
        return;
      }
      this._fire(new (Constructor(Resource))(resourceData));
    }

    function dispatchResourceContentEvent(
        this: APIImpl.EventSink<(resource: APIImpl.Resource, content: string) => unknown>,
        message: {arguments: unknown[]}): void {
      const resourceData = message.arguments[0] as APIImpl.ResourceData;
      if (!canAccessResource(resourceData)) {
        return;
      }
      this._fire(new (Constructor(Resource))(resourceData), message.arguments[1] as string);
    }

    this.onResourceAdded = new (Constructor(EventSink))(PrivateAPI.Events.ResourceAdded, dispatchResourceEvent);
    this.onResourceContentCommitted =
        new (Constructor(EventSink))(PrivateAPI.Events.ResourceContentCommitted, dispatchResourceContentEvent);
  }

  (InspectedWindow.prototype as Pick<PublicAPI.Chrome.DevTools.InspectedWindow, 'reload'|'eval'|'getResources'>) = {
    reload: function(optionsOrUserAgent: {
      ignoreCache?: boolean,
      injectedScript?: string,
      userAgent?: string,
    }): void {
      let options: {
        ignoreCache?: boolean,
        injectedScript?: string,
        userAgent?: string,
      }|null = null;
      if (typeof optionsOrUserAgent === 'object') {
        options = optionsOrUserAgent;
      } else if (typeof optionsOrUserAgent === 'string') {
        options = {userAgent: optionsOrUserAgent};
        console.warn(
            'Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. ' +
            'Use inspectedWindow.reload({ userAgent: value}) instead.');
      }
      extensionServer.sendRequest({command: PrivateAPI.Commands.Reload, options: options});
    },

    eval: function(
              expression: string,
              evaluateOptions: {scriptExecutionContext?: string, frameURL?: string, useContentScriptContext?: boolean}):
              Object |
        null {
          const callback = extractCallbackArgument(arguments);
          function callbackWrapper(result: unknown): void {
            const {isError, isException, value} = result as {
              isError?: boolean,
              isException?: boolean, value: unknown,
            };
            if (isError || isException) {
              callback && callback(undefined, result);
            } else {
              callback && callback(value);
            }
          }
          extensionServer.sendRequest(
              {
                command: PrivateAPI.Commands.EvaluateOnInspectedPage,
                expression: expression,
                evaluateOptions: (typeof evaluateOptions === 'object' ? evaluateOptions : undefined),
              },
              callback && callbackWrapper);
          return null;
        },

    getResources: function(callback?: (resources: PublicAPI.Chrome.DevTools.Resource[]) => unknown): void {
      function wrapResource(resourceData: APIImpl.ResourceData): APIImpl.Resource {
        return new (Constructor(Resource))(resourceData);
      }
      function callbackWrapper(resources: unknown): void {
        callback && callback((resources as APIImpl.ResourceData[]).filter(canAccessResource).map(wrapResource));
      }
      extensionServer.sendRequest({command: PrivateAPI.Commands.GetPageResources}, callback && callbackWrapper);
    },
  };

  function ResourceImpl(this: APIImpl.Resource, resourceData: APIImpl.ResourceData): void {
    if (!canAccessResource(resourceData)) {
      throw new Error('Resource access not allowed');
    }
    this._url = resourceData.url;
    this._type = resourceData.type;
  }

  (ResourceImpl.prototype as Pick<APIImpl.Resource, 'url'|'type'|'getContent'|'setContent'>) = {
    get url(): string {
      return (this as APIImpl.Resource)._url;
    },

    get type(): string {
      return (this as APIImpl.Resource)._type;
    },

    getContent: function(this: APIImpl.Resource, callback?: (content: string, encoding: string) => unknown): void {
      function callbackWrapper(response: unknown): void {
        const {content, encoding} = response as {content: string, encoding: string};
        callback && callback(content, encoding);
      }

      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.GetResourceContent, url: this._url}, callback && callbackWrapper);
    },

    setContent: function(
        this: APIImpl.Resource, content: string, commit: boolean, callback: (error?: Object) => unknown): void {
      extensionServer.sendRequest(
          {command: PrivateAPI.Commands.SetResourceContent, url: this._url, content: content, commit: commit},
          callback as (response: unknown) => unknown);
    },
  };

  function getTabId(): string {
    return inspectedTabId;
  }

  let keyboardEventRequestQueue: KeyboardEventInit&{eventType: string}[] = [];
  let forwardTimer: number|null = null;
  function forwardKeyboardEvent(event: KeyboardEvent): void {
    // Check if the event should be forwarded.
    // This is a workaround for crbug.com/923338.
    const focused = document.activeElement;
    if (focused) {
      const isInput =
          focused.nodeName === 'INPUT' || focused.nodeName === 'TEXTAREA' || (focused as HTMLElement).isContentEditable;
      if (isInput && !(event.ctrlKey || event.altKey || event.metaKey)) {
        return;
      }
    }

    let modifiers = 0;
    if (event.shiftKey) {
      modifiers |= 1;
    }
    if (event.ctrlKey) {
      modifiers |= 2;
    }
    if (event.altKey) {
      modifiers |= 4;
    }
    if (event.metaKey) {
      modifiers |= 8;
    }
    const num = (event.keyCode & 255) | (modifiers << 8);
    // We only care about global hotkeys, not about random text
    if (!keysToForwardSet.has(num)) {
      return;
    }
    event.preventDefault();
    const requestPayload = {
      eventType: event.type,
      ctrlKey: event.ctrlKey,
      altKey: event.altKey,
      metaKey: event.metaKey,
      shiftKey: event.shiftKey,
      // @ts-expect-error keyIdentifier is a deprecated non-standard property that typescript doesn't know about.
      keyIdentifier: event.keyIdentifier,
      key: event.key,
      code: event.code,
      location: event.location,
      keyCode: event.keyCode,
    };
    keyboardEventRequestQueue.push(requestPayload);
    if (!forwardTimer) {
      forwardTimer = window.setTimeout(forwardEventQueue, 0);
    }
  }

  function forwardEventQueue(): void {
    forwardTimer = null;
    extensionServer.sendRequest(
        {command: PrivateAPI.Commands.ForwardKeyboardEvent, entries: keyboardEventRequestQueue});
    keyboardEventRequestQueue = [];
  }

  document.addEventListener('keydown', forwardKeyboardEvent, false);

  function ExtensionServerClient(this: APIImpl.ExtensionServerClient, targetWindow: Window): void {
    this._callbacks = {};
    this._handlers = {};
    this._lastRequestId = 0;
    this._lastObjectId = 0;

    this.registerHandler('callback', this._onCallback.bind(this));

    const channel = new MessageChannel();
    this._port = channel.port1;
    this._port.addEventListener('message', this._onMessage.bind(this), false);
    this._port.start();

    targetWindow.postMessage('registerExtension', '*', [channel.port2]);
  }

  (ExtensionServerClient.prototype as Pick<
       APIImpl.ExtensionServerClient,
       'sendRequest'|'hasHandler'|'registerHandler'|'unregisterHandler'|'nextObjectId'|'_registerCallback'|
       '_onCallback'|'_onMessage'>) = {
    sendRequest: function<ResponseT>(
        this: APIImpl.ExtensionServerClient, message: PrivateAPI.ServerRequests,
        callback?: (response: ResponseT) => unknown, transfers?: Transferable[]): void {
      if (typeof callback === 'function') {
        (message as PrivateAPI.ExtensionServerRequestMessage).requestId =
            this._registerCallback(callback as (response: unknown) => unknown);
      }
      // @ts-expect-error
      this._port.postMessage(message, transfers);
    },

    hasHandler: function(this: APIImpl.ExtensionServerClient, command: string): boolean {
      return Boolean(this._handlers[command]);
    },

    registerHandler: function(
        this: APIImpl.ExtensionServerClient, command: string, handler: (request: {arguments: unknown[]}) => unknown):
        void {
          this._handlers[command] = handler;
        },

    unregisterHandler: function(this: APIImpl.ExtensionServerClient, command: string): void {
      delete this._handlers[command];
    },

    nextObjectId: function(this: APIImpl.ExtensionServerClient): string {
      return injectedScriptId.toString() + '_' + ++this._lastObjectId;
    },

    _registerCallback: function(this: APIImpl.ExtensionServerClient, callback: (response: unknown) => unknown): number {
      const id = ++this._lastRequestId;
      this._callbacks[id] = callback;
      return id;
    },

    _onCallback: function(this: APIImpl.ExtensionServerClient, request: {requestId: number, result: unknown}): void {
      if (request.requestId in this._callbacks) {
        const callback = this._callbacks[request.requestId];
        delete this._callbacks[request.requestId];
        callback(request.result);
      }
    },

    _onMessage: function(
        this: APIImpl.ExtensionServerClient,
        event: MessageEvent<{command: string, requestId: number, arguments: unknown[]}>): void {
      const request = event.data;
      const handler = this._handlers[request.command];
      if (handler) {
        handler.call(this, request);
      }
    },
  };

  function populateInterfaceClass(interfaze: {[key: string]: unknown}, implementation: {[key: string]: unknown}): void {
    for (const member in implementation) {
      if (member.charAt(0) === '_') {
        continue;
      }
      let descriptor: (PropertyDescriptor|undefined)|null = null;
      // Traverse prototype chain until we find the owner.
      for (let owner = implementation; owner && !descriptor; owner = owner.__proto__ as {[key: string]: unknown}) {
        descriptor = Object.getOwnPropertyDescriptor(owner, member);
      }
      if (!descriptor) {
        continue;
      }
      if (typeof descriptor.value === 'function') {
        interfaze[member] = descriptor.value.bind(implementation);
      } else if (typeof descriptor.get === 'function') {
        // @ts-expect-error
        interfaze.__defineGetter__(member, descriptor.get.bind(implementation));
      } else {
        Object.defineProperty(interfaze, member, descriptor);
      }
    }
  }

  const extensionServer = new (Constructor(ExtensionServerClient))(targetWindowForTest || window.parent);

  const coreAPI = new (Constructor(InspectorExtensionAPI))();

  Object.defineProperty(chrome, 'devtools', {value: {}, enumerable: true});

  // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
  // @ts-expect-error
  chrome.devtools!.inspectedWindow = {};
  Object.defineProperty(chrome.devtools!.inspectedWindow, 'tabId', {get: getTabId});
  // @ts-expect-error
  chrome.devtools!.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
  chrome.devtools!.network = coreAPI.network;
  chrome.devtools!.panels = coreAPI.panels;
  chrome.devtools!.panels.themeName = themeName;
  chrome.devtools!.languageServices = coreAPI.languageServices;
  chrome.devtools!.recorder = coreAPI.recorder;

  // default to expose experimental APIs for now.
  if (extensionInfo.exposeExperimentalAPIs !== false) {
    chrome.experimental = chrome.experimental || {};
    chrome.experimental.devtools = chrome.experimental.devtools || {};

    const properties = Object.getOwnPropertyNames(coreAPI);
    for (let i = 0; i < properties.length; ++i) {
      const descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
      if (descriptor) {
        Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
      }
    }
    chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
  }

  if (extensionInfo.exposeWebInspectorNamespace) {
    window.webInspector = coreAPI;
  }
  testHook(extensionServer, coreAPI);
};

self.buildExtensionAPIInjectedScript = function(
    extensionInfo: {
      startPage: string,
      name: string,
      exposeExperimentalAPIs: boolean,
    },
    inspectedTabId: string, themeName: string, keysToForward: number[],
    testHook:
        ((extensionServer: APIImpl.ExtensionServerClient, extensionAPI: APIImpl.InspectorExtensionAPI) => unknown)|
    undefined): string {
  const argumentsJSON =
      [extensionInfo, inspectedTabId || null, themeName, keysToForward].map(_ => JSON.stringify(_)).join(',');
  if (!testHook) {
    testHook = (): void => {};
  }
  return '(function(injectedScriptId){ ' +
      '(' + self.injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
      '})';
};
