import { LogLevel } from '@nestjs/common';
import { join, resolve } from 'path';
import { isObject, notNilEmpty } from 'qx-util';
import { readConfig, readGatewayConfig } from '../util/read-yaml';
import { setLoggerLevels } from '../../core';

// 配置文件根目录
const configBasePath = resolve(__dirname, '../../../configs');
// 读取环境变量
const { env } = process;
// 读取配置文件根路径
const configPath = notNilEmpty(env.APPLICATION_CONFIG_PATH)
  ? resolve(env.APPLICATION_CONFIG_PATH)
  : resolve(configBasePath, `application.yaml`);
// 读取配置文件
const data = readConfig(configPath) as Record<string, any>;
// 应用配置
const appConfig = data.app || {};
// runtime 配置
const runtimeConfig = data.runtime;
// caching 配置
const cachingConfig = data.caching;
// redis 配置
const redisConfig = data.redis;
// nacos 配置
const nacos = data.nacos;
// nacos 网关配置
const nacosGateway = {};
if (true) {
  const gatewayConfigPath = join(configBasePath, 'gateway.yaml');
  const data = readGatewayConfig(gatewayConfigPath);
  Object.assign(nacosGateway, data);
}
export const config: Record<string, any> = {
  app: {
    ...appConfig,
    port: notNilEmpty(env.APPLICATION_PORT) ? env.APPLICATION_PORT : appConfig.port,
  },
  log: data.log,
  static: data.static,
  runtime: {
    enable: runtimeConfig.enable,
  },
  caching: {
    ttl: cachingConfig.ttl,
  },
  redis: {
    enable: redisConfig.enable || false,
    host: redisConfig.host,
    port: redisConfig.port || 6379,
    ttl: redisConfig.ttl || 60 * 10,
    db: redisConfig.database,
    auth_pass: redisConfig.password,
  },
  nacos,
  default_api: data.default_api,
  ibiz: data.ibiz,
  dynamic: data.dynamic,
  gateway: nacosGateway,
};
// 整数字符串
const numberReg = /^\d*$/;

/**
 * 从环境变量提取配置
 *
 * @author chitanda
 * @date 2021-11-11 15:11:30
 * @param {string} [pEnvKey='']
 * @param {Record<string, any>} [data=config]
 */
function fillConfigByEnv(pEnvKey = '', data: Record<string, any> = config): void {
  for (const key in data) {
    if (Object.prototype.hasOwnProperty.call(data, key)) {
      const val = data[key];
      // 格式化 env 环境变量 key
      const envKey = pEnvKey + (pEnvKey === '' ? '' : '_') + formatKey(key);
      if (!Array.isArray(val) && isObject(val)) {
        fillConfigByEnv(envKey, val);
      } else {
        if (notNilEmpty(env[envKey])) {
          const envVal = env[envKey].trimStart().trimEnd();
          if (numberReg.test(envVal)) {
            data[key] = parseInt(envVal);
          } else if (envVal === 'true' || envVal === 'false') {
            data[key] = envVal === 'true' ? true : false;
          } else {
            data[key] = envVal;
          }
        }
      }
    }
  }
}

/**
 * 格式化为 env 环境变量标识，除首字母外 大写字母前加 _ (下划线)。
 *
 * @author chitanda
 * @date 2021-11-11 15:11:13
 * @param {string} key
 * @return {*}  {string}
 */
function formatKey(key: string): string {
  if (key === 'gateway') {
    return '';
  }
  const reg = /^[A-Z]$/;
  return key
    .split('')
    .map((str: string, i: number) => {
      if (i > 0 && reg.test(str)) {
        str = `_${str.toUpperCase()}`;
      }
      return str.toUpperCase();
    })
    .join('');
}
// 从环境变量提取 配置参数
fillConfigByEnv('', config);
// 设置日志级别
if (config.log.levels) {
  const levels = (config.log.levels as string).split(',') as LogLevel[];
  setLoggerLevels(levels);
}

/**
 * 应用配置
 */
export const AppConfigParams = () => config;
