using API.Controllers.DTOs;
using API.Schema.MangaContext;
using Asp.Versioning;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Soenneker.Utils.String.NeedlemanWunsch;
using static Microsoft.AspNetCore.Http.StatusCodes;
using Author = API.Controllers.DTOs.Author;
using Chapter = API.Controllers.DTOs.Chapter;
// ReSharper disable InconsistentNaming
namespace API.Controllers;
[ApiVersion(2)]
[ApiController]
[Route("v{v:apiVersion}/[controller]")]
public class QueryController(MangaContext context) : Controller
{
///
/// Returns the with
///
/// .Key
///
/// with not found
[HttpGet("Author/{AuthorId}")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
public async Task, NotFound>> GetAuthor (string AuthorId)
{
if (await context.Authors.FirstOrDefaultAsync(a => a.Key == AuthorId, HttpContext.RequestAborted) is not { } author)
return TypedResults.NotFound(nameof(AuthorId));
return TypedResults.Ok(new Author(author.Key, author.AuthorName));
}
///
/// Returns with
///
/// .Key
///
/// with not found
[HttpGet("Chapter/{ChapterId}")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
public async Task, NotFound>> GetChapter (string ChapterId)
{
if (await context.Chapters.FirstOrDefaultAsync(c => c.Key == ChapterId, HttpContext.RequestAborted) is not { } chapter)
return TypedResults.NotFound(nameof(ChapterId));
IEnumerable ids = chapter.MangaConnectorIds.Select(id =>
new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
return TypedResults.Ok(new Chapter(chapter.Key, chapter.ParentMangaId, chapter.VolumeNumber, chapter.ChapterNumber, chapter.Title,ids, chapter.Downloaded));
}
///
/// Returns the with .Key
///
/// Key of
///
/// with not found
[HttpGet("Manga/MangaConnectorId/{MangaConnectorIdId}")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
public async Task, NotFound>> GetMangaMangaConnectorId (string MangaConnectorIdId)
{
if (await context.MangaConnectorToManga.FirstOrDefaultAsync(c => c.Key == MangaConnectorIdId, HttpContext.RequestAborted) is not { } mcIdManga)
return TypedResults.NotFound(nameof(MangaConnectorIdId));
MangaConnectorId result = new (mcIdManga.Key, mcIdManga.MangaConnectorName, mcIdManga.ObjId, mcIdManga.WebsiteUrl, mcIdManga.UseForDownload);
return TypedResults.Ok(result);
}
///
/// Returns with names similar to (identified by )
///
/// Key of
///
/// with not found
/// Error during Database Operation
[HttpGet("Manga/{MangaId}/SimilarName")]
[ProducesResponseType>(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
[ProducesResponseType(Status500InternalServerError)]
public async Task>, NotFound, InternalServerError>> GetSimilarManga (string MangaId)
{
if (await context.Mangas.FirstOrDefaultAsync(m => m.Key == MangaId, HttpContext.RequestAborted) is not { } manga)
return TypedResults.NotFound(nameof(MangaId));
string name = manga.Name;
if (await context.Mangas.Where(m => m.Key != MangaId)
.ToDictionaryAsync(m => m.Key, m => m.Name, HttpContext.RequestAborted) is not { } mangaNames)
return TypedResults.InternalServerError();
List similarIds = mangaNames
.Where(kv => NeedlemanWunschStringUtil.CalculateSimilarityPercentage(name, kv.Value) > 0.8)
.Select(kv => kv.Key)
.ToList();
return TypedResults.Ok(similarIds);
}
///
/// Returns the with .Key
///
/// Key of
///
/// with not found
[HttpGet("Chapter/MangaConnectorId/{MangaConnectorIdId}")]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
public async Task, NotFound>> GetChapterMangaConnectorId (string MangaConnectorIdId)
{
if (await context.MangaConnectorToManga.FirstOrDefaultAsync(c => c.Key == MangaConnectorIdId, HttpContext.RequestAborted) is not { } mcIdChapter)
return TypedResults.NotFound(nameof(MangaConnectorIdId));
MangaConnectorId result = new(mcIdChapter.Key, mcIdChapter.MangaConnectorName, mcIdChapter.ObjId, mcIdChapter.WebsiteUrl, mcIdChapter.UseForDownload);
return TypedResults.Ok(result);
}
}