import type { OpenClawConfig } from "../config/config.js";
import { loadPluginManifestRegistry } from "../plugins/manifest-registry.js";

type ChannelEnvVarLookupParams = {
  config?: OpenClawConfig;
  workspaceDir?: string;
  env?: NodeJS.ProcessEnv;
};

function appendUniqueEnvVarCandidates(
  target: Record<string, string[]>,
  channelId: string,
  keys: readonly string[],
) {
  const normalizedChannelId = channelId.trim();
  if (!normalizedChannelId || keys.length === 0) {
    return;
  }
  const bucket = (target[normalizedChannelId] ??= []);
  const seen = new Set(bucket);
  for (const key of keys) {
    const normalizedKey = key.trim();
    if (!normalizedKey || seen.has(normalizedKey)) {
      continue;
    }
    seen.add(normalizedKey);
    bucket.push(normalizedKey);
  }
}

export function resolveChannelEnvVars(
  params?: ChannelEnvVarLookupParams,
): Record<string, readonly string[]> {
  const registry = loadPluginManifestRegistry({
    config: params?.config,
    workspaceDir: params?.workspaceDir,
    env: params?.env,
  });
  const candidates: Record<string, string[]> = Object.create(null) as Record<string, string[]>;
  for (const plugin of registry.plugins) {
    if (!plugin.channelEnvVars) {
      continue;
    }
    for (const [channelId, keys] of Object.entries(plugin.channelEnvVars).toSorted(
      ([left], [right]) => left.localeCompare(right),
    )) {
      appendUniqueEnvVarCandidates(candidates, channelId, keys);
    }
  }
  return candidates;
}

export function getChannelEnvVars(channelId: string, params?: ChannelEnvVarLookupParams): string[] {
  const channelEnvVars = resolveChannelEnvVars(params);
  const envVars = Object.hasOwn(channelEnvVars, channelId) ? channelEnvVars[channelId] : undefined;
  return Array.isArray(envVars) ? [...envVars] : [];
}

export function listKnownChannelEnvVarNames(params?: ChannelEnvVarLookupParams): string[] {
  return [...new Set(Object.values(resolveChannelEnvVars(params)).flatMap((keys) => keys))];
}
