const { logger } = require('@librechat/data-schemas');
const { normalizeEndpointName } = require('@librechat/api');
const { EModelEndpoint } = require('librechat-data-provider');

/**
 * Sets up Model Specs from the config (`librechat.yaml`) file.
 * @param {TCustomConfig['endpoints']} [endpoints] - The loaded custom configuration for endpoints.
 * @param {TCustomConfig['modelSpecs'] | undefined} [modelSpecs] - The loaded custom configuration for model specs.
 * @param {TCustomConfig['interface'] | undefined} [interfaceConfig] - The loaded interface configuration.
 * @returns {TCustomConfig['modelSpecs'] | undefined} The processed model specs, if any.
 */
function processModelSpecs(endpoints, _modelSpecs, interfaceConfig) {
  if (!_modelSpecs) {
    return undefined;
  }

  /** @type {TCustomConfig['modelSpecs']['list']} */
  const modelSpecs = [];
  /** @type {TCustomConfig['modelSpecs']['list']} */
  const list = _modelSpecs.list;

  const customEndpoints = endpoints?.[EModelEndpoint.custom] ?? [];

  if (interfaceConfig.modelSelect !== true && (_modelSpecs.addedEndpoints?.length ?? 0) > 0) {
    logger.warn(
      `To utilize \`addedEndpoints\`, which allows provider/model selections alongside model specs, set \`modelSelect: true\` in the interface configuration.

      Example:
      \`\`\`yaml
      interface:
        modelSelect: true
      \`\`\`
      `,
    );
  }

  for (const spec of list) {
    if (EModelEndpoint[spec.preset.endpoint] && spec.preset.endpoint !== EModelEndpoint.custom) {
      modelSpecs.push(spec);
      continue;
    } else if (spec.preset.endpoint === EModelEndpoint.custom) {
      logger.warn(
        `Model Spec with endpoint "${spec.preset.endpoint}" is not supported. You must specify the name of the custom endpoint (case-sensitive, as defined in your config). Skipping model spec...`,
      );
      continue;
    }

    const normalizedName = normalizeEndpointName(spec.preset.endpoint);
    const endpoint = customEndpoints.find(
      (customEndpoint) => normalizedName === normalizeEndpointName(customEndpoint.name),
    );

    if (!endpoint) {
      logger.warn(`Model spec with endpoint "${spec.preset.endpoint}" was skipped: Endpoint not found in configuration. The \`endpoint\` value must exactly match either a system-defined endpoint or a custom endpoint defined by the user.

For more information, see the documentation at https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/model_specs#endpoint`);
      continue;
    }

    modelSpecs.push({
      ...spec,
      preset: {
        ...spec.preset,
        endpoint: normalizedName,
      },
    });
  }

  return {
    ..._modelSpecs,
    list: modelSpecs,
  };
}

module.exports = { processModelSpecs };
