using API.Schema;
using API.Schema.Jobs;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using static Microsoft.AspNetCore.Http.StatusCodes;
namespace API.Controllers;
[ApiVersion(2)]
[ApiController]
[Produces("application/json")]
[Route("v{version:apiVersion}/[controller]")]
public class JobController(PgsqlContext context) : Controller
{
///
/// Returns all Jobs
///
/// Array of Jobs
[HttpGet]
[ProducesResponseType(Status200OK)]
public IActionResult GetAllJobs()
{
Job[] ret = context.Jobs.ToArray();
return Ok(ret);
}
///
/// Returns Jobs with requested Job-IDs
///
/// Array of Job-IDs
/// Array of Jobs
[HttpPost("WithIDs")]
[ProducesResponseType(Status200OK)]
public IActionResult GetJobs([FromBody]string[] ids)
{
Job[] ret = context.Jobs.Where(job => ids.Contains(job.JobId)).ToArray();
return Ok(ret);
}
///
/// Get all Jobs in requested State
///
/// Requested Job-State
/// Array of Jobs
[HttpGet("State/{state}")]
[ProducesResponseType(Status200OK)]
public IActionResult GetJobsInState(JobState state)
{
Job[] jobsInState = context.Jobs.Where(job => job.state == state).ToArray();
return Ok(jobsInState);
}
///
/// Returns all Jobs of requested Type
///
/// Requested Job-Type
/// Array of Jobs
[HttpGet("Type/{type}")]
[ProducesResponseType(Status200OK)]
public IActionResult GetJobsOfType(JobType type)
{
Job[] jobsOfType = context.Jobs.Where(job => job.JobType == type).ToArray();
return Ok(jobsOfType);
}
///
/// Return Job with ID
///
/// Job-ID
/// Job
[HttpGet("{id}")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status404NotFound)]
public IActionResult GetJob(string id)
{
Job? ret = context.Jobs.Find(id);
return (ret is not null) switch
{
true => Ok(ret),
false => NotFound()
};
}
///
/// Create a new CreateNewDownloadChapterJob
///
/// ID of the Manga, and how often we check again
/// Nothing
[HttpPut("NewDownloadChapterJob/{mangaId}")]
[ProducesResponseType(Status201Created)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult CreateNewDownloadChapterJob(string mangaId, [FromBody]ulong recurrenceTime)
{
Job job = new DownloadNewChaptersJob(recurrenceTime, mangaId);
return AddJob(job);
}
///
/// Create a new DownloadSingleChapterJob
///
/// ID of the Chapter
/// Nothing
[HttpPut("DownloadSingleChapterJob/{chapterId}")]
[ProducesResponseType(Status201Created)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult CreateNewDownloadChapterJob(string chapterId)
{
Job job = new DownloadSingleChapterJob(chapterId);
return AddJob(job);
}
///
/// Create a new UpdateMetadataJob
///
/// ID of the Manga
/// Nothing
[HttpPut("UpdateMetadataJob/{mangaId}")]
[ProducesResponseType(Status201Created)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult CreateUpdateMetadataJob(string mangaId)
{
Job job = new UpdateMetadataJob(0, mangaId);
return AddJob(job);
}
///
/// Create a new UpdateMetadataJob for all Manga
///
/// Nothing
[HttpPut("UpdateMetadataJob")]
[ProducesResponseType(Status201Created)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult CreateUpdateAllMetadataJob()
{
List ids = context.Manga.Select(m => m.MangaId).ToList();
List jobs = ids.Select(id => new UpdateMetadataJob(0, id)).ToList();
try
{
context.Jobs.AddRange(jobs);
context.SaveChanges();
return Created();
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
private IActionResult AddJob(Job job)
{
try
{
context.Jobs.Add(job);
context.SaveChanges();
return Created();
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
///
/// Delete Job with ID
///
/// Job-ID
/// Nothing
[HttpDelete("{id}")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status404NotFound)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult DeleteJob(string id)
{
try
{
Job? ret = context.Jobs.Find(id);
switch (ret is not null)
{
case true:
context.Remove(ret);
context.SaveChanges();
return Ok();
case false: return NotFound();
}
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
///
/// Starts the Job with the requested ID
///
/// Job-ID
/// Nothing
[HttpPost("{id}/Start")]
[ProducesResponseType(Status202Accepted)]
[ProducesResponseType(Status404NotFound)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult StartJob(string id)
{
Job? ret = context.Jobs.Find(id);
if (ret is null)
return NotFound();
ret.NextExecution = DateTime.UnixEpoch;
try
{
context.Update(ret);
context.SaveChanges();
return Accepted();
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
[HttpPost("{id}/Stop")]
public IActionResult StopJob(string id)
{
return NotFound(new ProblemResponse("Not implemented")); //TODO
}
}