import { TokenManager } from './token-manager.js';
import { AgentRegistryClient } from './services/agents.js';
import { CredentialClient } from './services/credentials.js';
import { TokenClient } from './services/token.js';
import { AuditClient } from './services/audit.js';
import type { AgentIdPClientConfig, OAuthScope } from './types.js';

/**
 * Top-level client for the SentryAgent.ai AgentIdP API.
 *
 * Composes all service clients under a single entry point.
 * Handles token acquisition and caching automatically via TokenManager.
 *
 * @example
 * ```typescript
 * const client = new AgentIdPClient({
 *   baseUrl: 'http://localhost:3000',
 *   clientId: 'your-agent-id',
 *   clientSecret: 'your-client-secret',
 * });
 *
 * const agents = await client.agents.listAgents();
 * ```
 */
export class AgentIdPClient {
  /** Agent Registry operations: register, list, get, update, decommission. */
  readonly agents: AgentRegistryClient;

  /** Credential operations: generate, list, rotate, revoke. */
  readonly credentials: CredentialClient;

  /** Token operations: introspect, revoke. */
  readonly tokens: TokenClient;

  /** Audit log operations: query, get event. */
  readonly audit: AuditClient;

  private readonly tokenManager: TokenManager;

  constructor(config: AgentIdPClientConfig) {
    const defaultScopes: OAuthScope[] = ['agents:read', 'agents:write', 'tokens:read', 'audit:read'];
    const scopes = (config.scopes ?? defaultScopes).join(' ');

    this.tokenManager = new TokenManager(
      config.baseUrl,
      config.clientId,
      config.clientSecret,
      scopes,
    );

    const getToken = () => this.tokenManager.getToken();

    this.agents = new AgentRegistryClient(config.baseUrl, getToken);
    this.credentials = new CredentialClient(config.baseUrl, getToken);
    this.tokens = new TokenClient(config.baseUrl, getToken);
    this.audit = new AuditClient(config.baseUrl, getToken);
  }

  /**
   * Clear the cached access token. The next API call will request a new token.
   * Use this after rotating credentials or when you suspect the token is stale.
   */
  clearTokenCache(): void {
    this.tokenManager.clearCache();
  }
}
