import type { IEmailDomainConfig } from './interfaces.js';
import { logger } from '../../logger.js';

/**
 * Registry for email domain configurations
 * Provides fast lookups and validation for domains
 */
export class DomainRegistry {
  private domains: Map<string, IEmailDomainConfig> = new Map();
  private defaults: IEmailDomainConfig['dkim'] & {
    dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
    rateLimits?: IEmailDomainConfig['rateLimits'];
  };
  
  constructor(
    domainConfigs: IEmailDomainConfig[],
    defaults?: {
      dnsMode?: 'forward' | 'internal-dns' | 'external-dns';
      dkim?: IEmailDomainConfig['dkim'];
      rateLimits?: IEmailDomainConfig['rateLimits'];
    }
  ) {
    // Set defaults
    this.defaults = {
      dnsMode: defaults?.dnsMode || 'external-dns',
      ...this.getDefaultDkimConfig(),
      ...defaults?.dkim,
      rateLimits: defaults?.rateLimits
    };
    
    // Process and store domain configurations
    for (const config of domainConfigs) {
      const processedConfig = this.applyDefaults(config);
      this.domains.set(config.domain.toLowerCase(), processedConfig);
      logger.log('info', `Registered domain: ${config.domain} with DNS mode: ${processedConfig.dnsMode}`);
    }
  }
  
  /**
   * Get default DKIM configuration
   */
  private getDefaultDkimConfig(): IEmailDomainConfig['dkim'] {
    return {
      selector: 'default',
      keySize: 2048,
      rotateKeys: false,
      rotationInterval: 90
    };
  }
  
  /**
   * Apply defaults to a domain configuration
   */
  private applyDefaults(config: IEmailDomainConfig): IEmailDomainConfig {
    return {
      ...config,
      dnsMode: config.dnsMode || this.defaults.dnsMode!,
      dkim: {
        ...this.getDefaultDkimConfig(),
        ...this.defaults,
        ...config.dkim
      },
      rateLimits: {
        ...this.defaults.rateLimits,
        ...config.rateLimits,
        outbound: {
          ...this.defaults.rateLimits?.outbound,
          ...config.rateLimits?.outbound
        },
        inbound: {
          ...this.defaults.rateLimits?.inbound,
          ...config.rateLimits?.inbound
        }
      }
    };
  }
  
  /**
   * Check if a domain is registered
   */
  isDomainRegistered(domain: string): boolean {
    return this.domains.has(domain.toLowerCase());
  }
  
  /**
   * Check if an email address belongs to a registered domain
   */
  isEmailRegistered(email: string): boolean {
    const domain = this.extractDomain(email);
    if (!domain) return false;
    return this.isDomainRegistered(domain);
  }
  
  /**
   * Get domain configuration
   */
  getDomainConfig(domain: string): IEmailDomainConfig | undefined {
    return this.domains.get(domain.toLowerCase());
  }
  
  /**
   * Get domain configuration for an email address
   */
  getEmailDomainConfig(email: string): IEmailDomainConfig | undefined {
    const domain = this.extractDomain(email);
    if (!domain) return undefined;
    return this.getDomainConfig(domain);
  }
  
  /**
   * Extract domain from email address
   */
  private extractDomain(email: string): string | null {
    const parts = email.toLowerCase().split('@');
    if (parts.length !== 2) return null;
    return parts[1];
  }
  
  /**
   * Get all registered domains
   */
  getAllDomains(): string[] {
    return Array.from(this.domains.keys());
  }
  
  /**
   * Get all domain configurations
   */
  getAllConfigs(): IEmailDomainConfig[] {
    return Array.from(this.domains.values());
  }
  
  /**
   * Get domains by DNS mode
   */
  getDomainsByMode(mode: 'forward' | 'internal-dns' | 'external-dns'): IEmailDomainConfig[] {
    return Array.from(this.domains.values()).filter(config => config.dnsMode === mode);
  }
}