using RackPeek.Domain.Helpers; using RackPeek.Domain.Persistence; namespace RackPeek.Domain.Resources.Services.UseCases; public class UpdateServiceUseCase(IResourceCollection repository) : IUseCase { public async Task ExecuteAsync( string name, string? ip = null, int? port = null, string? protocol = null, string? url = null, List? runsOn = null, string? notes = null ) { // ToDo pass in properties as inputs, construct the entity in the usecase, ensure optional inputs are nullable // ToDo validate / normalize all inputs name = Normalize.ServiceName(name); ThrowIfInvalid.ResourceName(name); var service = await repository.GetByNameAsync(name) as Service; if (service is null) throw new NotFoundException($"Service '{name}' not found."); if (ip != null) { service.Network ??= new Network(); service.Network.Ip = ip; } if (protocol != null) { service.Network ??= new Network(); service.Network.Protocol = protocol; } if (url != null) { service.Network ??= new Network(); service.Network.Url = url; } if (port.HasValue) { service.Network ??= new Network(); service.Network.Port = port.Value; } if (runsOn is not null) { var normalizedParents = new List(); foreach (var parent in runsOn .Where(p => !string.IsNullOrWhiteSpace(p)) .Select(p => p.Trim()) .Distinct(StringComparer.OrdinalIgnoreCase)) { ThrowIfInvalid.ResourceName(parent); Resource? parentSystem = await repository.GetByNameAsync(parent); if (parentSystem == null) throw new NotFoundException($"Parent system '{parent}' not found."); normalizedParents.Add(parent); } service.RunsOn = normalizedParents; } if (notes != null) service.Notes = notes; await repository.UpdateAsync(service); } }