import {Socket} from 'net'
export type IDictionary<T> = Record<string, T>

export interface SingleProxyOptions {
  address: string
  port: number
  handshakeTimeout?: number
  rpcReplyTimeout?: number
}

export interface ProxyPoolOptions {
  getAvailableProxy: () => SingleProxyOptions
  shouldUseProxy?: (data: {
    socket: Socket
    destinationInfo: AddressInfo
    originInfo: AddressInfo
  }) => boolean
}

export interface AddressInfo {
  address?: string
  port?: number
}

export interface FullSocks5ProxyOptions {
  shouldBlockPrivateAddresses: boolean
  shouldBlockRequest: (info: AddressInfo) => boolean
  proxyServer: SingleProxyOptions
  proxyServers: ProxyPoolOptions
  authenticate: (username: string, password: string, socket: Socket, onSuccess: () => void) => void
  connectionFilter: (
    destination: Partial<AddressInfo>,
    origin: Partial<AddressInfo>,
    callback: () => void,
  ) => void
}

export interface AuthenticateArgs {
  version: number
  requestBuffer: Buffer
  username: Buffer
  password: Buffer
}

export type Socks5ProxyOptions = Partial<FullSocks5ProxyOptions>

export interface SocketError extends Error {
  code: string
}
