import { Sponsor } from '@core/racing/domain/entities/sponsor/Sponsor'; import { SponsorRepository } from '@core/racing/domain/repositories/SponsorRepository'; import { Logger } from '@core/shared/domain'; export class InMemorySponsorRepository implements SponsorRepository { private sponsors: Map = new Map(); private emailIndex: Map = new Map(); // contactEmail -> sponsorId constructor(private readonly logger: Logger, initialSponsors: Sponsor[] = []) { this.logger.info('InMemorySponsorRepository initialized.'); for (const sponsor of initialSponsors) { this.sponsors.set(sponsor.id.toString(), sponsor); this.emailIndex.set(sponsor.contactEmail.toString().toLowerCase(), sponsor.id.toString()); this.logger.debug(`Seeded sponsor: ${sponsor.id} (${sponsor.name}).`); } } async findById(id: string): Promise { this.logger.debug(`[InMemorySponsorRepository] Finding sponsor by ID: ${id}`); const sponsor = this.sponsors.get(id) ?? null; if (sponsor) { this.logger.info(`Found sponsor by ID: ${id}.`); } else { this.logger.warn(`Sponsor with ID ${id} not found.`); } return Promise.resolve(sponsor); } async findAll(): Promise { this.logger.debug('[InMemorySponsorRepository] Finding all sponsors.'); return Promise.resolve(Array.from(this.sponsors.values())); } async findByEmail(email: string): Promise { this.logger.debug(`[InMemorySponsorRepository] Finding sponsor by email: ${email}`); const sponsorId = this.emailIndex.get(email.toLowerCase()); if (!sponsorId) { this.logger.warn(`Sponsor with email ${email} not found.`); return Promise.resolve(null); } return this.findById(sponsorId); } async create(sponsor: Sponsor): Promise { this.logger.debug(`[InMemorySponsorRepository] Creating sponsor: ${sponsor.id} (${sponsor.name})`); if (this.sponsors.has(sponsor.id.toString())) { this.logger.warn(`Sponsor with ID ${sponsor.id} already exists.`); throw new Error('Sponsor already exists'); } if (this.emailIndex.has(sponsor.contactEmail.toString().toLowerCase())) { this.logger.warn(`Sponsor with email ${sponsor.contactEmail} already exists.`); throw new Error('Sponsor with this email already exists'); } this.sponsors.set(sponsor.id.toString(), sponsor); this.emailIndex.set(sponsor.contactEmail.toString().toLowerCase(), sponsor.id.toString()); this.logger.info(`Sponsor ${sponsor.id} (${sponsor.name}) created successfully.`); return Promise.resolve(sponsor); } async update(sponsor: Sponsor): Promise { this.logger.debug(`[InMemorySponsorRepository] Updating sponsor: ${sponsor.id} (${sponsor.name})`); if (!this.sponsors.has(sponsor.id.toString())) { this.logger.warn(`Sponsor with ID ${sponsor.id} not found for update.`); throw new Error('Sponsor not found'); } const existingSponsor = this.sponsors.get(sponsor.id.toString()); // If email changed, update index if (existingSponsor && existingSponsor.contactEmail.toString().toLowerCase() !== sponsor.contactEmail.toString().toLowerCase()) { if (this.emailIndex.has(sponsor.contactEmail.toString().toLowerCase()) && this.emailIndex.get(sponsor.contactEmail.toString().toLowerCase()) !== sponsor.id.toString()) { this.logger.warn(`Cannot update sponsor ${sponsor.id} to email ${sponsor.contactEmail} as it's already taken.`); throw new Error('Sponsor with this email already exists'); } this.emailIndex.delete(existingSponsor.contactEmail.toString().toLowerCase()); this.emailIndex.set(sponsor.contactEmail.toString().toLowerCase(), sponsor.id.toString()); } this.sponsors.set(sponsor.id.toString(), sponsor); this.logger.info(`Sponsor ${sponsor.id} (${sponsor.name}) updated successfully.`); return Promise.resolve(sponsor); } async delete(id: string): Promise { this.logger.debug(`[InMemorySponsorRepository] Deleting sponsor with ID: ${id}`); const sponsor = this.sponsors.get(id); if (sponsor) { this.sponsors.delete(id); this.emailIndex.delete(sponsor.contactEmail.toString().toLowerCase()); this.logger.info(`Sponsor ${id} deleted successfully.`); } else { this.logger.warn(`Sponsor with ID ${id} not found for deletion.`); } return Promise.resolve(); } async exists(id: string): Promise { this.logger.debug(`[InMemorySponsorRepository] Checking existence of sponsor with ID: ${id}`); return Promise.resolve(this.sponsors.has(id)); } }