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; } }