using API.Schema.MangaContext;
using API.Schema.MangaContext.MangaConnectors;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using static Microsoft.AspNetCore.Http.StatusCodes;
// ReSharper disable InconsistentNaming
namespace API.Controllers;
[ApiVersion(2)]
[ApiController]
[Route("v{v:apiVersion}/[controller]")]
public class SearchController(IServiceScope scope) : Controller
{
///
/// Initiate a search for a on with searchTerm
///
/// .Name
/// searchTerm
///
/// with Name not found
/// with Name is disabled
[HttpGet("{MangaConnectorName}/{Query}")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound)]
[ProducesResponseType(Status406NotAcceptable)]
public IActionResult SearchManga(string MangaConnectorName, string Query)
{
MangaContext context = scope.ServiceProvider.GetRequiredService();
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector)
return NotFound();
if (connector.Enabled is false)
return StatusCode(Status412PreconditionFailed);
(Manga, MangaConnectorId)[] mangas = connector.SearchManga(Query);
List retMangas = new();
foreach ((Manga manga, MangaConnectorId mcId) manga in mangas)
{
if(AddMangaToContext(manga, context) is { } add)
retMangas.Add(add);
}
return Ok(retMangas.ToArray());
}
///
/// Returns from the associated with
///
///
///
/// Multiple found for URL
/// not found
/// Error during Database Operation
[HttpPost("Url")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound)]
[ProducesResponseType(Status500InternalServerError)]
public IActionResult GetMangaFromUrl([FromBody]string url)
{
MangaContext context = scope.ServiceProvider.GetRequiredService();
if (context.MangaConnectors.Find("Global") is not { } connector)
return StatusCode(Status500InternalServerError, "Could not find Global Connector.");
if(connector.GetMangaFromUrl(url) is not { } manga)
return NotFound();
if(AddMangaToContext(manga, context) is not { } add)
return StatusCode(Status500InternalServerError);
return Ok(add);
}
private Manga? AddMangaToContext((Manga, MangaConnectorId) manga, MangaContext context) => AddMangaToContext(manga.Item1, manga.Item2, context);
private static Manga? AddMangaToContext(Manga addManga, MangaConnectorId addMcId, MangaContext context)
{
Manga manga = context.Mangas.Find(addManga.Key) ?? addManga;
MangaConnectorId mcId = context.MangaConnectorToManga.Find(addMcId.Key) ?? addMcId;
mcId.Obj = manga;
IEnumerable mergedTags = manga.MangaTags.Select(mt =>
{
MangaTag? inDb = context.Tags.Find(mt.Tag);
return inDb ?? mt;
});
manga.MangaTags = mergedTags.ToList();
IEnumerable mergedAuthors = manga.Authors.Select(ma =>
{
Author? inDb = context.Authors.Find(ma.Key);
return inDb ?? ma;
});
manga.Authors = mergedAuthors.ToList();
if(context.MangaConnectorToManga.Find(addMcId.Key) is null)
context.MangaConnectorToManga.Add(mcId);
if (context.Sync().Result is not null)
return null;
return manga;
}
}