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

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

class TyApiConfig { ty_url: string };

class AliOssConfig {
    region: string;
    accessKeyId: string;
    accessKeySecret: string;
    bucket: string;
};

class RedisConfig {
    host: string;
    port: string;
    password: string;
    database: string;
}

class ImageMysqlConfig {
    host: string;
    port: number;
    user: string;
    password: string;
    database: string;
}

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

    //mysql________________________________________start
    @Value('mysql.host')
    static mysql_host: string;
    @Value('mysql.port')
    static mysql_port: string;
    @Value('mysql.db')
    static mysql_db: string;
    @Value('mysql.user')
    static mysql_user: string;
    @Value('mysql.pwd')
    static mysql_pwd: string;
    //mysql________________________________________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('alioss.region')
    static alioss_region: string
    @Value('alioss.accessKeyId')
    static alioss_accessKeyId: string
    @Value('alioss.accessKeySecret')
    static alioss_accessKeySecret: string
    @Value('alioss.bucket')
    static alioss_bucket: string
    //ali-oss________________________________________end

    //车场镜像库________________________________________start
    @Value('imageMysql.host')
    static imageMysql_host: string
    @Value('imageMysql.port')
    static imageMysql_port: number
    @Value('imageMysql.db')
    static imageMysql_db: string
    @Value('imageMysql.user')
    static imageMysql_user: string
    @Value('imageMysql.pwd')
    static imageMysql_pwd: string
    //车场镜像库________________________________________end
}

/**
 * 配置中心的配置provider
 */
export class ConfigCenterConfigProvider {
    static readonly RETRY_MS = 1000 * 15;
    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 = new TyApiConfig();
                    config.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) {
                if (error instanceof TyApiConfig) resolve(null);
                else reject(error);
            }
        });
    }

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

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config = new AliOssConfig();
                    config.region = ConfigCenterConfig.alioss_region;
                    config.accessKeyId = ConfigCenterConfig.alioss_accessKeyId;
                    config.accessKeySecret = ConfigCenterConfig.alioss_accessKeySecret;
                    config.bucket = ConfigCenterConfig.alioss_bucket;

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

                resolve(res);
            } catch (error) {
                if (error instanceof AliOssConfig) resolve(null);
                else reject(error);
            }
        });
    }

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

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config = new RedisConfig();
                    config.host = ConfigCenterConfig.reids_host;
                    config.port = ConfigCenterConfig.reids_port;
                    config.password = ConfigCenterConfig.reids_pwd;
                    config.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) {
                if (error instanceof RedisConfig) resolve(null);
                else reject(error);
            }
        });
    }

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

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config = new ImageMysqlConfig()
                    config.host = ConfigCenterConfig.imageMysql_host;
                    config.port = ConfigCenterConfig.imageMysql_port;
                    config.user = ConfigCenterConfig.imageMysql_user;
                    config.password = ConfigCenterConfig.imageMysql_pwd;
                    config.database = ConfigCenterConfig.imageMysql_db;

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

                resolve(res);
            } catch (error) {
                if (error instanceof ImageMysqlConfig) resolve(null);
                else reject(error);
            }
        });
    }
}