import type { McpServer } from '@prisma/client';
import type { ISecretRepository } from '../repositories/interfaces.js';
import type { ServerEnvEntry } from '../validation/mcp-server.schema.js';

/**
 * Resolve a server's env entries into a flat key-value map.
 * - Inline `value` entries are used directly.
 * - `valueFrom.secretRef` entries are looked up from the secret repository.
 * Throws if a referenced secret or key is missing.
 */
export async function resolveServerEnv(
  server: McpServer,
  secretRepo: ISecretRepository,
): Promise<Record<string, string>> {
  const entries = server.env as ServerEnvEntry[];
  if (!entries || entries.length === 0) return {};

  const result: Record<string, string> = {};
  const secretCache = new Map<string, Record<string, string>>();

  for (const entry of entries) {
    if (entry.value !== undefined) {
      result[entry.name] = entry.value;
    } else if (entry.valueFrom?.secretRef) {
      const { name: secretName, key } = entry.valueFrom.secretRef;

      if (!secretCache.has(secretName)) {
        const secret = await secretRepo.findByName(secretName);
        if (!secret) {
          throw new Error(`Secret '${secretName}' not found (referenced by server '${server.name}' env '${entry.name}')`);
        }
        secretCache.set(secretName, secret.data as Record<string, string>);
      }

      const data = secretCache.get(secretName)!;
      if (!(key in data)) {
        throw new Error(`Key '${key}' not found in secret '${secretName}' (referenced by server '${server.name}' env '${entry.name}')`);
      }
      result[entry.name] = data[key]!;
    }
  }

  return result;
}
