export type TargetInfo = {
  targetId: string;
  type?: string;
  title?: string;
  url?: string;
  attached?: boolean;
};

export type ConnectedTarget = {
  sessionId: string;
  targetId: string;
  targetInfo: TargetInfo;
};

export type RelayStatus = {
  extensionConnected: boolean;
  targetCount: number;
};

export type CdpCommand = {
  id: number;
  method: string;
  params?: unknown;
  sessionId?: string;
};

export type CdpResponse = {
  id: number;
  result?: unknown;
  error?: { message: string };
  sessionId?: string;
};

export type CdpEvent = {
  method: string;
  params?: unknown;
  sessionId?: string;
};

export type ExtensionForwardCommandMessage = {
  id: number;
  method: 'forwardCDPCommand';
  params: { method: string; params?: unknown; sessionId?: string };
};

export type ExtensionResponseMessage = {
  id: number;
  result?: unknown;
  error?: string;
};

export type ExtensionForwardEventMessage = {
  method: 'forwardCDPEvent';
  params: { method: string; params?: unknown; sessionId?: string };
};

export type ExtensionPingMessage = { method: 'ping' };
export type ExtensionPongMessage = { method: 'pong' };

export type ExtensionMessage = ExtensionResponseMessage | ExtensionForwardEventMessage | ExtensionPongMessage;

export type AttachedToTargetEvent = {
  sessionId: string;
  targetInfo: TargetInfo;
  waitingForDebugger?: boolean;
};

export type DetachedFromTargetEvent = {
  sessionId: string;
  targetId?: string;
};

export type UserRelay = {
  extensionWs: unknown | null;
  cdpClients: Set<unknown>;
  connectedTargets: Map<string, ConnectedTarget>;
  pingInterval: Timer | null;
  gracePeriodTimer: Timer | null;
  pendingExtension: Map<
    number,
    {
      resolve: (v: unknown) => void;
      reject: (e: Error) => void;
      timer: Timer;
    }
  >;
  nextExtensionId: number;
  extensionReconnectWaiters: Set<(connected: boolean) => void>;
};
