MyBookmark/Modules.Library.Domain/Interactors/MediaContent/Anime/CommonPropertiesService.cs
2024-09-04 23:08:56 +03:00

253 lines
13 KiB
C#

using Modules.Library.Domain.Entities;
using Modules.Library.Domain.Entities.MediaContent.CommonProperties;
using Modules.Library.Domain.Entities.MediaContent.Items.Anime;
using Modules.Library.Domain.Exceptions.Genre;
using Modules.Library.Domain.Gateways;
namespace Modules.Library.Domain.Interactors.MediaContent.Anime;
internal class CommonPropertiesService(ILanguageGateway languageGateway, IGenreGateway genreGateway)
{
#region Name
internal async Task AddName(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, NameType nameType, Guid languageId, string value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (!await languageGateway.AnyWhere(q => q.Id == languageId)) throw new Exception("Language is not found");
switch (nameType)
{
case NameType.Original:
AddNameOriginal(commonProperties, languageId, value);
break;
case NameType.OriginalInAnotherLanguage:
AddNameOriginalInAnotherLanguage(commonProperties, languageId, value);
break;
case NameType.Translation:
AddNameTranslation(commonProperties, languageId, value);
break;
case NameType.Abbreviation:
AddNameAbbreviation(commonProperties, languageId, value);
break;
default:
throw new NotImplementedException();
}
}
private static void AddNameOriginal(CommonProperties commonProperties, Guid languageId, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
if (commonProperties.Names.Any(q => q.Type == NameType.Original)) throw new Exception("Original name is already exist.");
commonProperties.Names.Add(new NameItem(languageId, NameType.Original, value));
}
private static void AddNameOriginalInAnotherLanguage(CommonProperties commonProperties, Guid languageId, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
if (languageId == commonProperties.Names.SingleOrDefault(q => q.Type == NameType.Original)?.LanguageId)
throw new Exception("Language must not match original name language");
if (commonProperties.Names.Any(q => q.Type == NameType.OriginalInAnotherLanguage && q.LanguageId == languageId))
throw new Exception("Name in following language is already exist.");
commonProperties.Names.Add(new NameItem(languageId, NameType.OriginalInAnotherLanguage, value));
}
private static void AddNameTranslation(CommonProperties commonProperties, Guid languageId, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
commonProperties.Names.Add(new NameItem(languageId, NameType.Translation, value));
}
private static void AddNameAbbreviation(CommonProperties commonProperties, Guid languageId, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
commonProperties.Names.Add(new NameItem(languageId, NameType.Abbreviation, value));
}
internal static void RemoveName(CommonProperties commonProperties, Guid nameId)
{
var name = GetName(commonProperties, nameId);
if (name.Type == NameType.Original) throw new Exception($"Unable to remove original name");
commonProperties.Names.Remove(name);
}
internal static void SetNameValue(CommonProperties commonProperties, Guid nameId, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
var name = GetName(commonProperties, nameId);
if (name.Type != NameType.Original && commonProperties.Names.Any(q => q.LanguageId == name.LanguageId && q.Value == value))
throw new Exception("Name item with in same language with same value is already exists");
name.SetValue(value);
}
private static NameItem GetName(CommonProperties commonProperties, Guid nameId) => commonProperties.Names.FirstOrDefault(q => q.Id == nameId) ??
throw new Exception($"Name with id [{nameId}] is not found");
#endregion
internal static void SetPreview(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, string url, MediaInfoType type)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
commonProperties.Preview ??= new MediaInfo(url, type);
commonProperties.Preview.Url = url;
}
internal static void DeletePreview(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
commonProperties.Preview = null;
}
#region Description
internal async Task AddDescription(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid languageId, bool isOriginal, string value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (isOriginal)
{
if (!await languageGateway.AnyWhere(q => q.Id == languageId)) throw new Exception("Language is not found");
if (commonProperties.Descriptions.Any(q => q.IsOriginal)) throw new Exception("Original description is already exist.");
}
if (!await languageGateway.AnyWhere(q => q.Id == languageId)) throw new Exception("Language is not found");
var description = new DescriptionItem(languageId, isOriginal, value);
commonProperties.Descriptions.Add(description);
}
internal static void RemoveDescription(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid descriptionId)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var description = GetDescription(commonProperties, descriptionId);
if (description.IsOriginal) throw new Exception($"Unable to remove original description");
commonProperties.Descriptions.Remove(description);
}
internal static void SetDescriptionValue(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid descriptionId, string value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var name = GetDescription(commonProperties, descriptionId);
SetDescriptionValue(commonProperties, name, value);
}
private static void SetDescriptionValue(CommonProperties commonProperties, DescriptionItem descriptionItem, string value)
{
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));
if (!descriptionItem.IsOriginal && commonProperties.Descriptions.Any(q => q.LanguageId == descriptionItem.LanguageId && q.Value == value))
throw new Exception("Descriptoin item with with same value is already exists");
descriptionItem.Value = value;
}
private static DescriptionItem GetDescription(CommonProperties commonProperties, Guid descriptionId)
{
return commonProperties.Descriptions.FirstOrDefault(q => q.Id == descriptionId) ??
throw new Exception($"Description with id [{descriptionId}] is not found");
}
#endregion
#region RelatedContent
internal static void AddRelatedContent(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, string url, MediaInfoType type)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url));
CheckIfCanAddOrEdit(commonProperties, url, type);
commonProperties.RelatedContent.Add(new MediaInfo(url, type));
}
internal static void EditRelatedContent(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid relatedContentId, string url, MediaInfoType type)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var relatedContent = GetRelatedContent(commonProperties, relatedContentId);
CheckIfCanAddOrEdit(commonProperties, url, type);
relatedContent.Url = url;
relatedContent.Type = type;
}
internal static void RemoveRelatedContent(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid relatedContentId)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var relatedContent = GetRelatedContent(commonProperties, relatedContentId);
//_relatedContent.Remove(relatedContent);
commonProperties.RelatedContent.Remove(relatedContent);
}
private static void CheckIfCanAddOrEdit(CommonProperties commonProperties, string url, MediaInfoType type)
{
if (commonProperties.RelatedContent.Any(q => q.Url == url && q.Type == type))
throw new Exception("Related content with same url and same type is already exists");
}
private static MediaInfo GetRelatedContent(CommonProperties commonProperties, Guid relatedContentId)
{
return commonProperties.RelatedContent.FirstOrDefault(q => q.Id == relatedContentId) ??
throw new Exception($"Related content with id [{relatedContentId}] is not found");
}
#endregion
#region Genre
internal async Task AddGenre(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid genreId, decimal? proportion)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (!await genreGateway.AnyWhere(q => q.Id == genreId)) throw new GenreIsNotFoundException();
commonProperties.Genres.Add(new GenreProportionItem(genreId, proportion));
}
internal static void SetGenreProportion(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid genreProportionId, decimal? proportion)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var genreProportion = commonProperties.Genres.First(q => q.GenreId == genreProportionId);
genreProportion.Proportion = proportion;
}
internal static void RemoveGenre(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, Guid genreProportionId, decimal? proportion)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
var genreProportion = commonProperties.Genres.First(q => q.GenreId == genreProportionId);
commonProperties.Genres.Remove(genreProportion);
}
#endregion
internal static void SetAnnouncementDate(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, DateTimeOffset value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (value == default) throw new ArgumentNullException(nameof(value));
commonProperties.AnnouncementDate = value;
}
internal static void SetEstimatedReleaseDate(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, DateTimeOffset value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (value == default) throw new ArgumentNullException(nameof(value));
if (commonProperties.AnnouncementDate.HasValue && value <= commonProperties.AnnouncementDate.Value)
throw new Exception("Estimated release date can not be less or equal to announcement date");
commonProperties.EstimatedReleaseDate = value;
}
internal static void SetReleaseDate(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId, DateTimeOffset value)
{
var commonProperties = GetCommonProperties(title, animeSeasonId, animeEpisodeId);
if (value == default) throw new ArgumentNullException(nameof(value));
if (commonProperties.AnnouncementDate.HasValue && value <= commonProperties.AnnouncementDate.Value)
throw new Exception("Release date can not be less or equal to announcement date");
commonProperties.ReleaseDate = value;
}
private static CommonProperties GetCommonProperties(AnimeTitle title, Guid? animeSeasonId, Guid? animeEpisodeId)
{
if (!animeSeasonId.HasValue && !animeEpisodeId.HasValue) return title.CommonProperties;
else if (animeSeasonId.HasValue && !animeEpisodeId.HasValue)
{
var season = title.Items.OfType<AnimeSeason>().First(q => q.Id == animeSeasonId);
return season.CommonProperties;
}
else if (!animeSeasonId.HasValue && animeEpisodeId.HasValue)
{
//set to unseason episode
var episode = title.Items.OfType<AnimeEpisode>().First(q => q.Id == animeEpisodeId);
return episode.CommonProperties;
}
else
{
var season = title.Items.OfType<AnimeSeason>().First(q => q.Id == animeSeasonId);
var episode = season.Episodes.First(q => q.Id == animeEpisodeId);
return episode.CommonProperties;
}
}
}