/**
 * 配置中心模块
 * @date 2022-08-13 21:44:54
 * @author 何华东
 */

import { logger, Value } from "mslib";
import { retry } from "./Retry";

type TyApiConfig = { ty_url: string };

type AliOssConfig = {
    region: string,
    accessKeyId: string,
    accessKeySecret: string,
    bucket: string,
    secure: boolean
};

type RedisConfig = {
    host: string,
    port: string,
    password: string,
    database: string,
}

type KnexConfig = {
    connection: {
        host: string,
        port: number,
        user: string,
        password: string,
        database: string,
        multipleStatements: boolean
    }
}

/**
 * 配置中心非标配置
 */
export class ConfigCenterConfig {
    //tyApi________________________________________start
    @Value('ty.url')
    static ty_url: string;
    //tyApi________________________________________end

    //redis________________________________________start
    @Value('redis.host')
    static reids_host: string;
    @Value('redis.port')
    static reids_port: string;
    @Value('redis.db')
    static reid_db: string;
    @Value('redis.pwd')
    static reids_pwd: string;
    //redis________________________________________end

    //ali-oss________________________________________start
    @Value('oss.region')
    static oss_region: string
    @Value('oss.accessKeyId')
    static oss_accessKeyId: string
    @Value('oss.accessKeySecret')
    static oss_accessKeySecret: string
    @Value('oss.bucket')
    static oss_bucket: string
    //ali-oss________________________________________end

    //车场镜像库________________________________________start
    @Value('imagePark.host')
    static imagePark_host: string
    @Value('imagePark.port')
    static imagePark_port: number
    @Value('imagePark.db')
    static imagePark_db: string
    @Value('imagePark.user')
    static imagePark_user: string
    @Value('imagePark.pwd')
    static imagePark_pwd: string
    //车场镜像库________________________________________end
}

/**
 * 配置中心的配置provider
 */
export class ConfigCenterConfigProvider {
    static readonly RETRY_MS = 1000 * 10;
    static readonly RETRY_DELAY_MS = 200;

    /**
     * 验证项目配置是否引用了NsConfig(配置中心)
     */
    static checkRefNsConfig() {
        let ref = false;

        try {
            require('cn.keytop.stc.config-client');
            ref = true;
        } catch (error) {
            // logger.trace('未引用NsConfig');
        }

        return ref;
    }

    /**
     * 获取配置中心-统一接口配置
     */
    static getTyApiConfig(): Promise<TyApiConfig> {
        if (!this.checkRefNsConfig()) return;

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config: TyApiConfig = {
                        ty_url: ConfigCenterConfig.ty_url,
                    };

                    return config;
                }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                    {
                        retryCondition: (res: TyApiConfig) => {
                            return !res.ty_url;
                        }
                    });

                resolve(res);
            } catch (error) {
                reject(`获取配置中心的统一接口配置失败,${error.toString()}`);
            }
        });
    }

    /**
     * 获取配置中心-ali-oss配置
     */
    static getAliOssConfig(): Promise<AliOssConfig> {
        if (!this.checkRefNsConfig()) return;

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config: AliOssConfig = {
                        region: ConfigCenterConfig.oss_region,
                        accessKeyId: ConfigCenterConfig.oss_accessKeyId,
                        accessKeySecret: ConfigCenterConfig.oss_accessKeySecret,
                        bucket: ConfigCenterConfig.oss_bucket,
                        secure: true
                    };

                    return config;
                }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                    {
                        retryCondition: (res: AliOssConfig) => {
                            return !res.region;
                        }
                    });

                resolve(res);
            } catch (error) {
                logger.error(`获取配置中心的ali-oss配置失败`,error);
                reject(`获取配置中心的ali-oss配置失败,${error.toString()}`);
            }
        });
    }

    /**
     * 获取配置中心-redis配置
     */
    static getRedisConfig(): Promise<RedisConfig> {
        if (!this.checkRefNsConfig()) return;

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config: RedisConfig = {
                        host: ConfigCenterConfig.reids_host,
                        port: ConfigCenterConfig.reids_port,
                        password: ConfigCenterConfig.reids_pwd,
                        database: ConfigCenterConfig.reid_db,
                    };

                    return config;
                }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                    {
                        retryCondition: (res: RedisConfig) => {
                            return !res.host;
                        }
                    });

                resolve(res);
            } catch (error) {
                reject(`获取配置中心的redis配置失败,${error.toString()}`);
            }
        });
    }

    /**
     * 获取车场镜像knex配置
     */
    static getParkImageKnexConfig(): Promise<KnexConfig> {
        if (!this.checkRefNsConfig()) return;

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config: KnexConfig = {
                        connection: {
                            host: ConfigCenterConfig.imagePark_host,
                            port: ConfigCenterConfig.imagePark_port,
                            user: ConfigCenterConfig.imagePark_user,
                            password: ConfigCenterConfig.imagePark_pwd,
                            database: ConfigCenterConfig.imagePark_db,
                            multipleStatements: true,
                        }
                    };

                    return config;
                }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                    {
                        retryCondition: (res: KnexConfig) => {
                            return !res.connection.host;
                        }
                    });

                resolve(res);
            } catch (error) {
                reject(`获取配置中心的车场镜像knex配置失败,${error.toString()}`);
            }
        });
    }
}