// 用户相关请求模块
import Protobuf from 'protobufjs';
class ProtobufCtr {
    protoBufer: any;
    constructor() { }
    /**
     * 加载proto文件
     * @param {*} proto 导入的proto
     */
    public async loadProto(proto: string): Promise<any> {
        return new Promise((resolve, reject) => {
            Protobuf.loadProtoFile(proto, (err: Error, builder: any) => {
                if (err) {
                    console.error(err);
                    reject(err);
                }
                this.protoBufer = builder;
                resolve(builder);
            });
        });
    }

    /**
     * 生成proto实例
     * @param {*} protoName 需要实例化的proto构造函数
     */
    generateProtoInstence(protoName: string) {
        if (this.protoBufer) {
            const RootProto = this.protoBufer.build(protoName);
            if (RootProto) {
                const instenceProto = new RootProto();
                const set = new WeakSet()
                // 处理 proto 嵌套问题
                RootProto.$type.children.forEach((el: any) => {
                    const { resolvedType, name } = el;
                    if (resolvedType && typeof resolvedType === 'object') {
                        if (!set.has(resolvedType)) {
                            // 防止 proto 错误，导致一直在递归 
                            set.add(resolvedType)
                            instenceProto[name] = this.generateProtoInstence(resolvedType.name)
                        }
                    }
                });
                return instenceProto;
            } else {
                console.warn(`没有读取到${protoName}的实例`)
            }

        }
        console.error('没有找到protoBufer相关数据');
    }

    /**
     *
     * @param {*} protoName protoName名
     * @param {*} content 需要解析的内容
     */
    generateProtoContent(protoName: string, content: any) {
        const result = this.generateProtoConstructor(protoName);
        return result.decode64(content);
    }

    /**
     * 生成proto构造函数
     * @param {*} protoName protoName名
     */
    private generateProtoConstructor(protoName: string) {
        if (this.protoBufer) {
            const protoConstructor = this.protoBufer.build(protoName);
            if (!protoConstructor) {
                console.error('接收报文装箱失败');
            }
            return protoConstructor;
        }
        console.error('没有找到protoBufer相关数据');
    }
}

export default new ProtobufCtr();
