// Strategy registration helpers for kernel-only code.
//
// Core owns deterministic strategy registration.
// Package strategies are registered through externally provided loaders.

import type { RunStrategy } from "./contract";
import { globalStrategyRegistry } from "./registry";
import { DeterministicStrategy } from "./deterministic";

type StrategyLoader = () => Promise<RunStrategy>;

const strategyLoaders = new Map<string, StrategyLoader>();

export function registerStrategyLoader(name: string, loader: StrategyLoader): void {
  strategyLoaders.set(name, loader);
}

export function hasStrategyLoader(name: string): boolean {
  return strategyLoaders.has(name);
}

export function listStrategyLoaders(): string[] {
  return Array.from(strategyLoaders.keys()).sort();
}

export function registerDeterministic(): void {
  if (!globalStrategyRegistry.has("deterministic")) {
    globalStrategyRegistry.register(new DeterministicStrategy());
  }
  globalStrategyRegistry.setActive("deterministic");
}

async function registerFromLoader(name: string): Promise<void> {
  if (globalStrategyRegistry.has(name)) {
    return;
  }

  const loader = strategyLoaders.get(name);
  if (!loader) {
    throw new Error(`No strategy loader registered for "${name}"`);
  }

  const strategy = await loader();
  globalStrategyRegistry.register(strategy);
}

export async function registerStrategyByName(name: string): Promise<void> {
  await registerFromLoader(name);
}

export async function registerNondeterministic(): Promise<void> {
  await registerFromLoader("nondeterministic");
}

export async function registerSearch(): Promise<void> {
  await registerFromLoader("search");
}

export async function registerStochastic(): Promise<void> {
  await registerFromLoader("stochastic");
}

export async function registerComposed(): Promise<void> {
  await registerFromLoader("composed");
}

export async function registerAllStrategies(): Promise<void> {
  registerDeterministic();

  // Attempt best-effort registration for optional package strategies.
  await Promise.allSettled([
    registerNondeterministic(),
    registerSearch(),
    registerStochastic(),
    registerComposed(),
  ]);
}
