import * as yaml from 'js-yaml';
import { readFileSync } from 'fs';
import { logger } from '@/core';
import { notNilEmpty } from 'qx-util';
import { dirname, resolve } from 'path';
import { mergeDeepLeft } from 'ramda';
import { pathExistsSync } from 'fs-extra';

/**
 * 读取yaml配置文件
 *
 * @author chitanda
 * @date 2021-08-17 15:08:15
 * @exports
 * @param {string} path
 * @return {*}  {Record<string, any>}
 */
export function readYaml(path: string): Record<string, any> {
  try {
    const file = readFileSync(path, 'utf-8');
    const data = yaml.load(file);
    return data;
  } catch (err) {
    logger.error('', `yaml文件[${path}]解析异常!`, err);
  }
}

/**
 * 读取继承配置文件
 *
 * @author chitanda
 * @date 2022-02-22 16:02:24
 * @export
 * @param {string} configPath
 * @return {*}  {Record<string, unknown>}
 */
export function readDeepConfig(configPath: string): Record<string, unknown> {
  if (!pathExistsSync(configPath)) {
    throw new Error(`配置文件 ${configPath} 不存在`);
  }
  let config = readYaml(configPath);
  if (notNilEmpty(config.extends)) {
    const arr: string[] = config.extends;
    const configs: Record<string, unknown>[] = [];
    for (let i = 0; i < arr.length; i++) {
      const str = arr[i];
      const path = resolve(dirname(configPath), str);
      const parentConfig = readGatewayConfig(path);
      configs.push(parentConfig);
    }
    configs.reverse().forEach(parentConfig => {
      config = mergeDeepLeft(config, parentConfig);
    });
    delete config.extends;
  }
  return config;
}

/**
 * 读取网关配置文件
 *
 * @author chitanda
 * @date 2022-02-22 16:02:56
 * @export
 * @param {string} configPath
 * @return {*}  {Record<string, unknown>}
 */
export function readGatewayConfig(configPath: string): Record<string, unknown> {
  return readDeepConfig(configPath);
}

/**
 * 读取全局变量
 *
 * @author chitanda
 * @date 2022-02-22 16:02:33
 * @export
 * @param {string} configPath
 * @return {*}  {Record<string, unknown>}
 */
export function readConfig(configPath: string): Record<string, unknown> {
  return readDeepConfig(configPath);
}
