import Protobuf from 'protobufjs'

export default new (class {
    private readonly protoRoot: Promise<unknown>;

    /**
     * 加载proto文件
     */
    constructor() {
        this.protoRoot = new Promise((resolve, reject) => {
            Protobuf.load('./proto/thj.proto', (err: Error, root: unknown) => {
                if (err) {
                    reject(err)
                } else {
                    resolve(root)
                }
            })
        })
    }

    /**
     * 创建proto实例
     * @param protoName 需要实例化的proto构造函数
     */
    // eslint-disable-next-line
    build(protoName: string): Promise<any> {
        return new Promise((resolve, reject) => {
            // eslint-disable-next-line
            this.protoRoot.then((root: any) => {
                const build = root.lookup(protoName);
                resolve(build);
            }).catch(() => {
                reject('proto文件加载失败');
            })
        })
    }

    /**
     * proto请求编码
     * @param protoName 
     * @param payload 
     * @returns 
     */
    async requestEncode<T>(protoName: string, payload: T): Promise<Uint8Array> {
        const build = await this.build(protoName);
        return build.encode(payload).finish();
    }

    /**
     * proto响应解码
     * @param protoName 
     * @param content 
     * @returns 
     */
    async responseDecode<T>(protoName: string, content?: Uint8Array): Promise<T> {
        const build = await this.build(protoName);
        return build.decode(content);
    }
})