import {cosmiconfig, PublicExplorer} from 'cosmiconfig';
import {SCConfigFile} from '@openstapps/core';
import path from 'path';
import deepmerge from 'deepmerge';
import {Logger} from '@openstapps/logger';

const fallbackNamespace = 'default';
const configPath = 'config';

/**
 * Creates a config loader
 * @param moduleName the name of the config file (module)
 */
function configLoader(moduleName: string): PublicExplorer {
  return cosmiconfig(moduleName, {
    searchPlaces: ['js', 'json', 'yml', 'yaml'].map(it => `${moduleName}rc.${it}`),
    loaders: {
      '.js': filepath => import(`file://${filepath}`).then(it => it.default),
    },
  });
}

/**
 * Find and load a config file
 */
async function findConfig<T>(moduleName: string, namespace = fallbackNamespace): Promise<T> {
  const config = await configLoader(moduleName).search(path.posix.join('.', configPath, namespace));

  if (config) {
    Logger.info(`Using ${namespace} config for ${moduleName}`);
    return config.config;
  } else {
    Logger.info(`Using ${fallbackNamespace} config for ${moduleName}`);
    return configLoader(moduleName)
      .search(path.posix.join('.', configPath, fallbackNamespace))
      .then(it => it!.config);
  }
}

const namespace = process.env.NODE_APP_INSTANCE;
const database = process.env.NODE_CONFIG_ENV;

export const prometheusConfig = await findConfig<unknown>('prometheus', namespace);

const backendConfigWithoutDatabase = await findConfig<SCConfigFile>('backend', namespace);
export const backendConfig = database
  ? deepmerge(backendConfigWithoutDatabase, await findConfig<never>(database, namespace))
  : backendConfigWithoutDatabase;
