import { SuccessResponse, ErrorResponse, SubscriptionResponse } from "./Response";
import { Socket } from "./interfaces/Socket";

export type Visibility = "127.0.0.1" | "0.0.0.0"
export type Name = string

export type SocketConf = {
    connectionHandler: (socket:Socket) => void
    errorHandler: (socket:Socket) => (error:any) => void
    closeHandler: (socket:Socket) => () =>  void
    visibility: Visibility
}

export type rpcType = 'Hook' | 'Unhook' | 'Call'

export type BaseRPC = { 
    type: rpcType
    name: string
}

export type HookRPC = BaseRPC & {
    type: 'Hook'
    func: CallbackFunction
    unhook: UnhookFunction
}

export type UnhookRPC = BaseRPC & {
    type: 'Unhook'
    func: UnhookFunction
}

export type CallRPC = BaseRPC & {
    type: 'Call'
    func: (...args) => Promise<any>
}

export type SocketioRPC = CallRPC | UnhookRPC | HookRPC

export type BaseInfo = {
    owner: string,
    argNames: string[],
}

export type HookInfo = BaseRPC & BaseInfo & { 
    type: 'Hook', 
    generator: (socket) => CallbackFunction
    unhook: UnhookFunction
}

export type UnhookInfo = BaseRPC & BaseInfo & {
    type: 'Unhook',
    func: UnhookFunction
}

export type CallInfo = BaseRPC & BaseInfo & {
    type: 'Call',
    func: AsyncFunction
}

export type RpcInfo = HookInfo | UnhookInfo | CallInfo
export type ExtendedRpcInfo = RpcInfo & { uniqueName: string } 

export type OnFunction = (type: 'error' | 'close', f: (e?:any)=>void) => Socket
export type UnhookFunction = (uid:string) => Promise<SuccessResponse | ErrorResponse>
export type CallbackFunction = (...args) => Promise<SubscriptionResponse | ErrorResponse>
export type AsyncFunction = (...args) => Promise<any>
