/**
 * Context Provider Registry
 *
 * Factory for creating and managing context providers.
 */

import type { KuzuConnection } from '../graph/connection.js';
import { ContextProvider, type ProviderConstructor } from './providers/base.js';
import { ExploredAreasProvider } from './providers/explored-areas.js';
import { TouchedAreasProvider } from './providers/touched-areas.js';
import type { ContextProviderSpec } from './types.js';

/**
 * Context Provider Registry
 *
 * Manages registered providers and creates instances.
 */
export class ContextProviderRegistry {
  private static providers: Map<string, ProviderConstructor> = new Map();

  /**
   * Register a provider class
   */
  static register(name: string, ProviderClass: ProviderConstructor): void {
    ContextProviderRegistry.providers.set(name, ProviderClass);
  }

  /**
   * Get a provider instance by name
   */
  static get(
    name: string,
    conn?: KuzuConnection,
    config?: Record<string, unknown>
  ): ContextProvider | null {
    const ProviderClass = ContextProviderRegistry.providers.get(name);
    if (!ProviderClass) return null;
    return new ProviderClass(conn, config);
  }

  /**
   * Get all registered provider names
   */
  static getNames(): string[] {
    return Array.from(ContextProviderRegistry.providers.keys());
  }

  /**
   * Get specs for all registered providers
   */
  static getSpecs(): ContextProviderSpec[] {
    const specs: ContextProviderSpec[] = [];
    for (const [, ProviderClass] of ContextProviderRegistry.providers) {
      const instance = new ProviderClass();
      specs.push(instance.spec);
    }
    return specs;
  }

  /**
   * Check if a provider is registered
   */
  static has(name: string): boolean {
    return ContextProviderRegistry.providers.has(name);
  }

  /**
   * Clear all registered providers
   */
  static clear(): void {
    ContextProviderRegistry.providers.clear();
  }
}

// Auto-register built-in providers
ContextProviderRegistry.register('explored_areas', ExploredAreasProvider);
ContextProviderRegistry.register('touched_areas', TouchedAreasProvider);

/**
 * Get enabled providers from environment
 */
export function getEnabledProviders(): string[] {
  const envValue = process.env.CONTEXT_PROVIDERS;
  if (!envValue) {
    return ['explored_areas', 'touched_areas'];
  }
  return envValue.split(',').map((s) => s.trim()).filter(Boolean);
}

/**
 * Create provider instances for enabled providers
 */
export function createEnabledProviders(
  conn?: KuzuConnection,
  config?: Record<string, unknown>
): ContextProvider[] {
  const enabledNames = getEnabledProviders();
  const providers: ContextProvider[] = [];

  for (const name of enabledNames) {
    const provider = ContextProviderRegistry.get(name, conn, config);
    if (provider) {
      providers.push(provider);
    }
  }

  return providers;
}
