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

 import { Value } from "mslib";
 import { retry } from "./Retry";
 
 /**
  * 统一接口配置
  */
 class TyApiConfig {
     /**
      * 统一接口地址
      */
     ty_url: string;
 };
 
 /**
  * ali-oss配置
  */
 class AliOssConfig {
     region: string;
     accessKeyId: string;
     accessKeySecret: string;
     bucket: string;
 };
 
 /**
  * 华为Obs配置
  */
 class HuaweiObsConfig {
     server: string;
     access_key_id: string;
     secret_access_key: string;
     bucket:string;
 };
 
 /**
  * redis配置
  */
 class RedisConfig {
     host: string;
     port: string;
     password: string;
     database: string;
 }
 
 class MySqlConnectionOpts {
     host: string;
     port: number;
     user: string;
     password: string;
     database: string;
 }
 
 class NSConfig {
     //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: number;
     @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
 
     //华为obs________________________________________start
     @Value('obs.endpoint')
     static obs_endpoint: string
     @Value('obs.accessKeyId')
     static obs_accessKeyId: string
     @Value('obs.accessKeySecret')
     static obs_accessKeySecret: string
     @Value('obs.bucket')
     static obs_bucket: string
     //华为obs________________________________________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 {
     /**
      * 重试毫秒数
      */
     private static readonly RETRY_MS = 1000 * 20;
 
     /**
      * 每次重试延迟毫秒数
      */
     private static readonly RETRY_DELAY_MS = 500;
 
     /**
      * 验证是否已引用`NsConfig`
      */
     static checkRefNsConfig() {
         let ref = false;
 
         try {
             require('cn.keytop.stc.config-client');
             ref = true;
         } catch {}
 
         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 = NSConfig.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 = NSConfig.alioss_region;
                     config.accessKeyId = NSConfig.alioss_accessKeyId;
                     config.accessKeySecret = NSConfig.alioss_accessKeySecret;
                     config.bucket = NSConfig.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);
             }
         });
     }
 
     /**
      * 获取配置中心/`华为obs`配置
      */
     static getHuaweiObsConfig(): Promise<HuaweiObsConfig> {
         if (!this.checkRefNsConfig()) return;
 
         return new Promise(async (resolve, reject) => {
             try {
                 let res = await retry(() => {
                     let config = new HuaweiObsConfig();
                     config.server = NSConfig.obs_endpoint;
                     config.access_key_id = NSConfig.obs_accessKeyId;
                     config.secret_access_key = NSConfig.obs_accessKeySecret;
                     config.bucket = NSConfig.obs_bucket;
 
                     return config;
                 }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                     {
                         retryCondition: (res: HuaweiObsConfig) => {
                             return !res.server;
                         }
                     });
 
                 resolve(res);
             } catch (error) {
                 if (error instanceof HuaweiObsConfig) 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 = NSConfig.reids_host;
                     config.port = NSConfig.reids_port;
                     config.password = NSConfig.reids_pwd;
                     config.database = NSConfig.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<MySqlConnectionOpts> {
         if (!this.checkRefNsConfig()) return;
 
         return new Promise(async (resolve, reject) => {
             try {
                 let res = await retry(() => {
                     let config = new MySqlConnectionOpts()
                     config.host = NSConfig.imageMysql_host;
                     config.port = NSConfig.imageMysql_port;
                     config.user = NSConfig.imageMysql_user;
                     config.password = NSConfig.imageMysql_pwd;
                     config.database = NSConfig.imageMysql_db;
 
                     return config;
                 }, this.RETRY_MS / this.RETRY_DELAY_MS, this.RETRY_DELAY_MS,
                     {
                         retryCondition: (res: MySqlConnectionOpts) => {
                             return !res.host;
                         }
                     });
 
                 resolve(res);
             } catch (error) {
                 if (error instanceof MySqlConnectionOpts) resolve(null);
                 else reject(error);
             }
         });
     }

     static getMySqlConnectionOpts(): Promise<MySqlConnectionOpts> {
        if (!this.checkRefNsConfig()) return;

        return new Promise(async (resolve, reject) => {
            try {
                let res = await retry(() => {
                    let config = new MySqlConnectionOpts()
                    config.host = NSConfig.mysql_host;
                    config.port = NSConfig.mysql_port;
                    config.user = NSConfig.mysql_user;
                    config.password = NSConfig.mysql_pwd;
                    config.database = NSConfig.mysql_db;

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

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