using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Application.ThirdPartyModules.Queries;
///
/// Query to read the license text of a third-party module.
/// Either or must be provided, but not both.
///
public record ReadThirdPartyModuleLicenseQuery : IRequest
{
///
/// The unique identifier of the third-party module (optional).
///
public int? Id { get; init; }
///
/// The name of the third-party module (optional).
///
public string? Name { get; init; }
///
/// Whether to filter only active modules. Defaults to true.
///
public bool Active { get; init; } = true;
}
///
/// Handles and returns the license text of a third-party module.
///
public class ReadThirdPartyModuleLicenseQueryHandler : IRequestHandler
{
private readonly IRepository _repository;
///
/// Initializes a new instance of the class.
///
/// The repository for accessing third-party modules.
public ReadThirdPartyModuleLicenseQueryHandler(IRepository repository)
{
_repository = repository;
}
///
/// Handles the query by filtering on Id or Name and returning the license text.
///
/// The query parameters.
/// A cancellation token.
/// The license text of the matching third-party module.
///
/// Thrown when neither Id nor Name is provided, or when both are provided.
///
///
/// Thrown when multiple modules match the given criteria, indicating a data integrity issue.
///
///
/// Thrown when no module matches the given criteria.
///
public async Task Handle(ReadThirdPartyModuleLicenseQuery request, CancellationToken cancel)
{
if (request.Id is null && request.Name is null)
throw new BadRequestException("Either Id or Name must be provided.");
if (request.Id is not null && request.Name is not null)
throw new BadRequestException("Only one of Id or Name must be provided, not both.");
var query = _repository.Query
.Where(m => m.Active == request.Active);
if (request.Id is int id)
query = query.Where(m => m.Id == id);
if (request.Name is string name)
query = query.Where(m => m.Name == name);
var modules = await query
.Take(2)
.ToListAsync(cancel);
if (modules.Count > 1)
throw new InvalidOperationException(
$"Data integrity violation: multiple third-party modules found for the given criteria (Id={request.Id}, Name={request.Name}, Active={request.Active}).");
return modules.SingleOrDefault() is ThirdPartyModule module
? module.License
: throw new NotFoundException(
$"Third-party module not found for the given criteria (Id={request.Id}, Name={request.Name}, Active={request.Active}).");
}
}