/*!
 * TSRPC Proto v1.4.3
 * -----------------------------------------
 * Copyright (c) Kingworks Corporation.
 * MIT License
 * https://github.com/k8w/tsrpc-proto
 */
import { bigint64 } from 'tsbuffer-schema';
import { biguint64 } from 'tsbuffer-schema';
import { int } from 'tsbuffer-schema';
import { Overwrite } from 'tsbuffer-schema';
import { TSBufferProto } from 'tsbuffer-schema';
import { TSBufferSchema } from 'tsbuffer-schema';
import { uint } from 'tsbuffer-schema';

/**
 * The return of `client.callApi()`
 */
export declare type ApiReturn<Res> = ApiReturnSucc<Res> | ApiReturnError;

/**
 * Unified error, include network error, business error, code exception etc.
 */
export declare interface ApiReturnError {
    isSucc: false;
    res?: undefined;
    err: TsrpcError;
}

/**
 * Successful by `call.succ()`
 */
export declare interface ApiReturnSucc<Res> {
    isSucc: true;
    res: Res;
    err?: undefined;
}

/**
 * Send request and wait for response
 * @remarks
 * SchemaId of request and ressponse is generated by client, named with the prefix `Req` or `Res`.
 */
export declare interface ApiServiceDef extends BaseServiceDef {
    type: 'api';
    /**
     * Auto generated by `tsrpc-cli`
     * @example
     * ```ts title="PtlAddComment.ts"
     * export interface ReqAddComment {
     *     articleId: string;
     *     comment: string;
     * }
     *
     * export interface ResAddComment {
     *     commentId: string;
     * }
     *
     * // This would be auto generated to `service.conf`
     * export const conf = {
     *     needLogin: true,
     *     needRoles: ['SuperAdmin', 'ArticleAdmin', 'CommentAdmin']
     * };
     * ```
     */
    conf?: {
        [key: string]: any;
    };
}

export declare interface BaseServiceDef {
    id: number;
    name: string;
}

/**
 * API service request and response type, and Msg service type.
 * For coding auto hint.
 */
export declare interface BaseServiceType {
    /** Send a request, and wait for a response */
    api: {
        [apiName: string]: {
            /** Request type */
            req: any;
            /** Response type */
            res: any;
        };
    };
    /** Msg service, listen or send one-way msg without response  */
    msg: {
        /** Msg type */
        [msgName: string]: any;
    };
}

export { bigint64 }

export { biguint64 }

export { int }

/**
 * An abstract logger interface, which can be used to customize log behaviour.
 * Usually, you can pass `console` for convinience.
 * Or you can write your own implementation, for example, to report to a log system, or hide some log output.
 */
export declare interface Logger {
    debug(...args: any[]): void;
    log(...args: any[]): void;
    warn(...args: any[]): void;
    error(...args: any[]): void;
}

export declare type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';

/**
 * Send or listen specific data, without waiting for response.
 */
export declare interface MsgServiceDef extends BaseServiceDef {
    type: 'msg';
    conf?: {
        [key: string]: any;
    };
}

export { Overwrite }

/**
 * Basic transport data unit,
 * which represents data that server received, which should be sent by `client.callApi` or `client.sendMsg`.
 */
export declare interface ServerInputData {
    serviceId: uint;
    buffer: Uint8Array;
    /** Short link don't need this */
    sn?: uint;
}

/**
 * Basic transport data unit,
 * which represents data that server sent by `call.succ` or `call.error` or `conn.sendMsg`.
 */
export declare interface ServerOutputData {
    /** ApiResponse or Msg */
    buffer?: Uint8Array;
    /** Api Error, cannot exists at the same time with `buffer` */
    error?: TsrpcErrorData;
    /** Short link apiRes don't need this */
    serviceId?: uint;
    /** Short link don't need this */
    sn?: uint;
}

export declare type ServiceDef = ApiServiceDef | MsgServiceDef;

/**
 * TSRPC Server Protocol Definitions
 * @typeParam ServiceType - API request and response types, and Msg types.
 */
export declare interface ServiceProto<ServiceType extends BaseServiceType = any> {
    version?: number;
    /**
     * Service is the basic interactive unit for server and client.
     * Include {@link ApiServiceDef} and {@link MsgServiceDef}.
     */
    services: ServiceDef[];
    /**
     * `TSBufferProto` that includes all types used by the services.
     * @see
     * {@link tsbuffer-schema#TSBufferProto | TSBufferProto}
     * {@link tsbuffer-schema#TSBufferSchema | TSBufferSchema}
     */
    types: TSBufferProto;
    /** For IntelliSense in VSCode */
    __SERVICE_TYPE__?: ServiceType;
}

export declare function setLogLevel(logger: Logger, logLevel: LogLevel): Logger;

export declare const TransportDataProto: {
    ServerInputData: TSBufferSchema;
    ServerOutputData: TSBufferSchema;
    [key: string]: TSBufferSchema;
};

/**
 * A unified Error that returned by TSRPC server or client
 *
 * @remarks
 * It has many uses, for example:
 *
 * 1. You can handle business errors and network errors uniformly.
 * 2. In API handle process, `throw new TsrpcError('xxx')` would return the same error to client directly (like `call.error()`),
 * while `throw new Error('XXX')` would return a unified "Server Internal Error".
 */
export declare class TsrpcError implements TsrpcErrorData {
    static Type: typeof TsrpcErrorType;
    message: string;
    type: TsrpcErrorType;
    code?: string | int;
    [key: string]: any;
    constructor(data: TsrpcErrorData);
    /**
     * The `type` is `ApiError` by default
     */
    constructor(message: string, data?: Partial<TsrpcErrorData>);
    toString(): string;
}

export declare interface TsrpcErrorData {
    message: string;
    /**
     * @defaultValue ApiError
     */
    type: TsrpcErrorType;
    code?: string | int;
    [key: string]: any;
}

export declare enum TsrpcErrorType {
    /** Network error, like connection broken, network timeout, etc. */
    NetworkError = "NetworkError",
    /**
     * Server exception, for example "request format error", "database exception", etc.
     *
     * @remarks
     * This error message may be not suitable to show to user,
     * but the error info is useful for engineer to find some bug.
     * So you can show a user-friendly message to user (like "System error, please contact XXX"),
     * and report some debug info at the same time.
     */
    ServerError = "ServerError",
    /** Client exception, for example parse server output error.
     * (May because of the proto file is not the same between server and client)
     */
    ClientError = "ClientError",
    /**
     * The business error returned by `call.error`.
     * It is always business-relatived, for example `call.error('Password is incorrect')`, `call.error('Not enough credit')`, etc.
     */
    ApiError = "ApiError"
}

export { uint }

export { }
