using API.APIEndpointRecords; using API.Schema.MangaContext; using API.Workers; using Asp.Versioning; using log4net; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; using static Microsoft.AspNetCore.Http.StatusCodes; // ReSharper disable InconsistentNaming namespace API.Controllers; [ApiVersion(2)] [ApiController] [Route("v{version:apiVersion}/[controller]")] public class WorkerController(ILog Log) : Controller { /// /// Returns all /// /// [HttpGet] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetAllWorkers() { return Ok(Tranga.Workers.ToArray()); } /// /// Returns with requested /// /// Array of .Key /// [HttpPost("WithIDs")] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobs([FromBody]string[] WorkerIds) { return Ok(Tranga.Workers.Where(worker => WorkerIds.Contains(worker.Key)).ToArray()); } /// /// Get all in requested /// /// Requested /// [HttpGet("State/{State}")] [ProducesResponseType(Status200OK, "application/json")] public IActionResult GetJobsInState(WorkerExecutionState State) { return Ok(Tranga.Workers.Where(worker => worker.State == State).ToArray()); } /// /// Return with /// /// .Key /// /// with could not be found [HttpGet("{WorkerId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound)] public IActionResult GetJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); return Ok(worker); } /// /// Delete with and all child-s /// /// .Key /// /// with could not be found [HttpDelete("{WorkerId}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult DeleteJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); Tranga.RemoveWorker(worker); return Ok(); } /// /// Modify with /// /// .Key /// Fields to modify, set to null to keep previous value /// /// /// with could not be found /// is not , can not modify [HttpPatch("{WorkerId}")] [ProducesResponseType(Status202Accepted, "application/json")] [ProducesResponseType(Status400BadRequest)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status409Conflict, "text/plain")] public IActionResult ModifyJob(string WorkerId, [FromBody]ModifyWorkerRecord modifyWorkerRecord) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if(modifyWorkerRecord.IntervalMs is not null && worker is not IPeriodic) return Conflict("Can not modify Interval of non-Periodic worker"); else if(modifyWorkerRecord.IntervalMs is not null && worker is IPeriodic periodic) periodic.Interval = TimeSpan.FromMilliseconds((long)modifyWorkerRecord.IntervalMs); return Accepted(worker); } /// /// Starts with /// /// .Key /// /// with could not be found /// was already running [HttpPost("{WorkerId}/Start")] [ProducesResponseType(Status202Accepted)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status412PreconditionFailed, "text/plain")] public IActionResult StartJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if (worker.State >= WorkerExecutionState.Waiting) return StatusCode(Status412PreconditionFailed, "Already running"); Tranga.StartWorker(worker); return Ok(); } /// /// Stops with /// /// .Key /// /// with could not be found /// was not running [HttpPost("{WorkerId}/Stop")] [ProducesResponseType(Status501NotImplemented)] public IActionResult StopJob(string WorkerId) { if(Tranga.Workers.FirstOrDefault(w => w.Key == WorkerId) is not { } worker) return NotFound(nameof(WorkerId)); if(worker.State is < WorkerExecutionState.Running or >= WorkerExecutionState.Completed) return StatusCode(Status208AlreadyReported, "Not running"); Tranga.StopWorker(worker); return Ok(); } }