export interface SesInfraBootstrapper {
  ensureConfigurationSet(name: string): Promise<void>;
  ensureSnsTopic(name: string): Promise<string>;
  ensureTopicPublishPermission(topicArn: string): Promise<void>;
  ensureHttpsSubscription(topicArn: string, endpoint: string): Promise<void>;
  ensureEventDestination(configurationSetName: string, topicArn: string): Promise<void>;
}

interface BootstrapSesInfraUseCaseRequest {
  configurationSetName: string;
  snsTopicName: string;
  webhookEndpoint: string;
}

interface BootstrapSesInfraUseCaseResponse {
  configurationSetName: string;
  topicArn: string;
}

/** Provisiona de forma idempotente o Configuration Set + tópico SNS + event destination
 * necessários para que os envios do SES gerem eventos rastreáveis (SEND/DELIVERY/BOUNCE/
 * COMPLAINT/REJECT/OPEN/CLICK) recebidos pelo webhook da aplicação. Pensado para ser chamado
 * por um script de setup (`scripts/bootstrap-ses.ts`) ou por uma rota admin protegida. */
export class BootstrapSesInfraUseCase {
  constructor(private infra: SesInfraBootstrapper) {}

  async execute({
    configurationSetName,
    snsTopicName,
    webhookEndpoint,
  }: BootstrapSesInfraUseCaseRequest): Promise<BootstrapSesInfraUseCaseResponse> {
    await this.infra.ensureConfigurationSet(configurationSetName);
    const topicArn = await this.infra.ensureSnsTopic(snsTopicName);
    await this.infra.ensureTopicPublishPermission(topicArn);
    await this.infra.ensureHttpsSubscription(topicArn, webhookEndpoint);
    await this.infra.ensureEventDestination(configurationSetName, topicArn);

    return { configurationSetName, topicArn };
  }
}
