import { Global, Module } from '@nestjs/common';
import { AgentRuntimeProviderRegistry, HermesRuntimeProvider } from '@mosaicstack/agent';
import { AgentService } from './agent.service.js';
import { ProviderService } from './provider.service.js';
import { ProviderCredentialsService } from './provider-credentials.service.js';
import { RoutingService } from './routing.service.js';
import { RoutingEngineService } from './routing/routing-engine.service.js';
import { SkillLoaderService } from './skill-loader.service.js';
import { ProvidersController } from './providers.controller.js';
import { SessionsController } from './sessions.controller.js';
import { AgentConfigsController } from './agent-configs.controller.js';
import { InteractionController } from './interaction.controller.js';
import { RoutingController } from './routing/routing.controller.js';
import { DurableSessionRepository } from './durable-session.repository.js';
import { DurableSessionService } from './durable-session.service.js';
import { CoordModule } from '../coord/coord.module.js';
import { McpClientModule } from '../mcp-client/mcp-client.module.js';
import { SkillsModule } from '../skills/skills.module.js';
import { GCModule } from '../gc/gc.module.js';
import { LogModule } from '../log/log.module.js';
import { CommandsModule } from '../commands/commands.module.js';
import { CommandRuntimeApprovalVerifier } from '../commands/runtime-approval-verifier.js';
import { GatewayHermesRuntimeTransport } from './hermes-runtime.transport.js';
import {
  AGENT_RUNTIME_PROVIDER_REGISTRY,
  RUNTIME_APPROVAL_VERIFIER,
  RUNTIME_PROVIDER_AUDIT_SINK,
  RuntimeProviderAuditService,
  RuntimeProviderService,
} from './runtime-provider-registry.service.js';

export function createGatewayRuntimeProviderRegistry(): AgentRuntimeProviderRegistry {
  const registry = new AgentRuntimeProviderRegistry();
  registry.register(new HermesRuntimeProvider(new GatewayHermesRuntimeTransport()));
  return registry;
}

@Global()
@Module({
  imports: [CoordModule, McpClientModule, SkillsModule, GCModule, LogModule, CommandsModule],
  providers: [
    ProviderService,
    ProviderCredentialsService,
    RoutingService,
    RoutingEngineService,
    SkillLoaderService,
    DurableSessionRepository,
    DurableSessionService,
    {
      provide: AGENT_RUNTIME_PROVIDER_REGISTRY,
      useFactory: createGatewayRuntimeProviderRegistry,
    },
    RuntimeProviderAuditService,
    {
      provide: RUNTIME_PROVIDER_AUDIT_SINK,
      useExisting: RuntimeProviderAuditService,
    },
    {
      provide: RUNTIME_APPROVAL_VERIFIER,
      useExisting: CommandRuntimeApprovalVerifier,
    },
    RuntimeProviderService,
    AgentService,
  ],
  controllers: [
    ProvidersController,
    SessionsController,
    AgentConfigsController,
    InteractionController,
    RoutingController,
  ],
  exports: [
    AgentService,
    ProviderService,
    ProviderCredentialsService,
    RoutingService,
    RoutingEngineService,
    SkillLoaderService,
    DurableSessionService,
    RuntimeProviderService,
    AGENT_RUNTIME_PROVIDER_REGISTRY,
  ],
})
export class AgentModule {}
