using System.ComponentModel.DataAnnotations; using ErsatzTV.Application.Filler; using ErsatzTV.Controllers.Api.Requests; using ErsatzTV.Core; using ErsatzTV.Core.Api.Filler; using ErsatzTV.Core.Domain.Filler; using ErsatzTV.Extensions; using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace ErsatzTV.Controllers.Api; [ApiController] public class FillerPresetController(IMediator mediator) : ControllerBase { [HttpGet("/api/filler-presets", Name = "GetFillerPresets")] [Tags("Filler Presets")] [EndpointSummary("Get all filler presets")] [EndpointDescription("Optionally filter to a single filler kind via the fillerKind query parameter.")] [EndpointGroupName("general")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task> GetAll( [FromQuery] FillerKind? fillerKind, CancellationToken cancellationToken) => await mediator.Send(new GetAllFillerPresetsForApi(fillerKind), cancellationToken); [HttpGet("/api/filler-presets/{id:int}", Name = "GetFillerPresetById")] [Tags("Filler Presets")] [EndpointSummary("Get a filler preset by id")] [EndpointGroupName("general")] [ProducesResponseType(typeof(FillerPresetFullResponseModel), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] public async Task GetById(int id, CancellationToken cancellationToken) { Option result = await mediator.Send(new GetFillerPresetByIdForApi(id), cancellationToken); return result.ToGetResult(); } [HttpPost("/api/filler-presets", Name = "CreateFillerPreset")] [Tags("Filler Presets")] [EndpointSummary("Create a filler preset")] [EndpointGroupName("general")] [ProducesResponseType(typeof(FillerPresetFullResponseModel), StatusCodes.Status201Created)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)] public async Task Create( [Required] [FromBody] CreateFillerPresetRequest request, CancellationToken cancellationToken) { Either result = await mediator.Send(request.ToCommand(), cancellationToken); return await result.Match( Left: error => Task.FromResult(error.ToErrorResult()), Right: async created => { Option fillerPreset = await mediator.Send(new GetFillerPresetByIdForApi(created.FillerPresetId), cancellationToken); return fillerPreset.Match( Some: vm => (IActionResult)new CreatedResult($"/api/filler-presets/{vm.Id}", vm), None: () => ApiResults.NotFoundProblem()); }); } [HttpPut("/api/filler-presets/{id:int}", Name = "UpdateFillerPreset")] [Tags("Filler Presets")] [EndpointSummary("Update a filler preset")] [EndpointGroupName("general")] [ProducesResponseType(typeof(FillerPresetFullResponseModel), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)] public async Task Update( int id, [Required] [FromBody] UpdateFillerPresetRequest request, CancellationToken cancellationToken) { Either result = await mediator.Send(request.ToCommand(id), cancellationToken); return await result.Match( Left: error => Task.FromResult(error.ToErrorResult()), Right: async _ => { Option fillerPreset = await mediator.Send(new GetFillerPresetByIdForApi(id), cancellationToken); return fillerPreset.Match( Some: vm => (IActionResult)new OkObjectResult(vm), None: () => ApiResults.NotFoundProblem()); }); } [HttpDelete("/api/filler-presets/{id:int}", Name = "DeleteFillerPreset")] [Tags("Filler Presets")] [EndpointSummary("Delete a filler preset")] [EndpointGroupName("general")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status401Unauthorized)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)] public async Task Delete(int id, CancellationToken cancellationToken) { Either result = await mediator.Send(new DeleteFillerPreset(id), cancellationToken); return result.ToDeletedResult(); } }