using ErsatzTV.Application.Libraries; using ErsatzTV.Core.Api.Libraries; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Extensions; using MediatR; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; namespace ErsatzTV.Controllers.Api; [ApiController] [EndpointGroupName("general")] public class LibrariesController(ITelevisionRepository televisionRepository, IMediator mediator) : ControllerBase { [HttpGet("/api/libraries/scan-status", Name = "GetLibraryScanStatus")] [Tags("Libraries")] [EndpointSummary("Get active library scan status")] [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] public async Task> GetScanStatus(CancellationToken cancellationToken) => await mediator.Send(new GetLibraryScanStatus(), cancellationToken); [HttpPost("/api/libraries/{id:int}/scan")] [Tags("Libraries")] [EndpointSummary("Scan library")] [ProducesResponseType(StatusCodes.Status202Accepted)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status409Conflict)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)] public async Task ScanLibrary(int id, CancellationToken cancellationToken) { QueueLibraryScanResult result = await mediator.Send(new QueueLibraryScanByLibraryId(id), cancellationToken); return result switch { QueueLibraryScanResult.Queued => new AcceptedResult(), QueueLibraryScanResult.AlreadyScanning => ApiResults.ConflictProblem( "Library scan in progress", $"A scan for library {id} is already in progress."), QueueLibraryScanResult.SyncDisabled => new UnprocessableEntityObjectResult( new ProblemDetails { Status = StatusCodes.Status422UnprocessableEntity, Title = "Library sync is disabled", Detail = $"Item sync is disabled for library {id}." }), _ => ApiResults.NotFoundProblem($"Library {id} does not exist.") }; } [HttpPost("/api/libraries/{id:int}/scan-show")] [Tags("Libraries")] [EndpointSummary("Scan show")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task ScanShow(int id, [FromBody] ScanShowRequest request) { Option maybeTitle = await televisionRepository.GetShowTitle(id, request.ShowId); foreach (string title in maybeTitle) { bool result = await mediator.Send(new QueueShowScanByLibraryId(id, request.ShowId, title, request.DeepScan)); return result ? new OkResult() : new BadRequestObjectResult(new { error = "Unable to queue show scan. Library may not exist, may not support single show scanning, or may already be scanning." }); } return ApiResults.NotFoundProblem($"Show {request.ShowId} does not exist in library {id}."); } } public record ScanShowRequest(int ShowId, bool DeepScan = false);