using System.Text.Json; using HrynCo.NotificationService.DAL.Abstract.Providers; using HrynCo.NotificationService.DAL.Abstract.Repositories; using HrynCo.NotificationService.DAL.EF.Core; using HrynCo.NotificationService.DAL.EF.Entities; using Microsoft.EntityFrameworkCore; namespace HrynCo.NotificationService.DAL.EF.Repositories; internal sealed class ProviderRepository : EfRepository, IProviderRepository { public ProviderRepository(NotificationDbContext dbContext) : base(dbContext) { } public async Task> GetByServiceAsync(string serviceName, CancellationToken ct = default) { List entities = await DbSet .Where(x => x.ServiceName == serviceName) .OrderBy(x => x.Priority) .ToListAsync(ct); return entities.Select(MapToDomain).ToList(); } public async Task GetByIdAsync(Guid id, CancellationToken ct = default) { ProviderEntity? entity = await DbSet.FindAsync([id], ct); return entity is null ? null : MapToDomain(entity); } public Task AddAsync(Provider provider, CancellationToken ct = default) => base.AddAsync(MapToEntity(provider), ct); public Task UpdateAsync(Provider provider, CancellationToken ct = default) { ProviderEntity entity = MapToEntity(provider); entity.Updated = DateTimeOffset.UtcNow; return base.UpdateAsync(entity, ct); } public async Task DeleteAsync(Provider provider, CancellationToken ct = default) { ProviderEntity? entity = await DbSet.FindAsync([provider.Id], ct); if (entity is not null) await base.DeleteAsync(entity, ct); } private static Provider MapToDomain(ProviderEntity e) => new() { Id = e.Id, ServiceName = e.ServiceName, Priority = e.Priority, ProviderType = e.ProviderType, Settings = DeserializeSettings(e.ProviderType, e.SettingsJson), DailyLimit = e.DailyLimit, MonthlyLimit = e.MonthlyLimit, WarnThresholdPercent = e.WarnThresholdPercent, IsActive = e.IsActive, Created = e.Created, Updated = e.Updated }; private static ProviderEntity MapToEntity(Provider p) => new() { Id = p.Id, ServiceName = p.ServiceName, Priority = p.Priority, ProviderType = p.ProviderType, SettingsJson = JsonSerializer.Serialize(p.Settings), DailyLimit = p.DailyLimit, MonthlyLimit = p.MonthlyLimit, WarnThresholdPercent = p.WarnThresholdPercent, IsActive = p.IsActive, Created = p.Created, Updated = p.Updated }; private static ProviderSettings DeserializeSettings(ProviderType type, string json) => type switch { ProviderType.Smtp => JsonSerializer.Deserialize(json) ?? throw new InvalidOperationException("Failed to deserialize SMTP provider settings."), _ => throw new InvalidOperationException($"Unknown provider type: {type}") }; }