sumatube/SumaTube.Application/Videos/ApplicationServices/VideoApplicationService.cs
2025-04-21 23:01:55 -03:00

138 lines
5.2 KiB
C#

using Microsoft.Extensions.Logging;
using SumaTube.Application.Videos.Contracts;
using SumaTube.Domain.Entities.Videos;
using SumaTube.Infra.Contracts.Repositories.Videos;
using SumaTube.Infra.VideoSumarizer.Contracts;
using SumaTube.Infra.VideoSumarizer.Videos;
namespace SumaTube.Application.Videos.ApplicationServices
{
public class VideoApplicationService : IVideoApplicationService
{
private readonly IVideoSummaryRepository _repository;
private readonly IVideoSumarizerService _sumarizerService;
private readonly ILogger<VideoApplicationService> _logger;
public VideoApplicationService(
IVideoSummaryRepository repository,
IVideoSumarizerService sumarizerService,
ILogger<VideoApplicationService> logger)
{
_repository = repository;
_sumarizerService = sumarizerService;
_logger = logger;
}
public async Task<List<VideoSummary>> GetUserVideosAsync(string userId)
{
_logger.LogInformation("Obtendo videos do usuário: {UserId}", userId);
return await _repository.GetByUserIdAsync(userId);
}
public async Task<VideoSummary> GetVideoSummaryByIdAsync(string id, string userId)
{
_logger.LogInformation("Obtendo resumo com ID: {SummaryId} para usuário: {UserId}", id, userId);
var summary = await _repository.GetByIdAsync(id);
if (summary == null || summary.UserId != userId)
{
_logger.LogWarning("Resumo não encontrado ou acesso não autorizado. ID: {SummaryId}, UserId: {UserId}", id, userId);
return null;
}
return summary;
}
public async Task<VideoSummary> RequestVideoSummaryAsync(string youtubeUrl, string language, string userId)
{
_logger.LogInformation("Solicitando resumo para URL: {Url}, idioma: {Language}, usuário: {UserId}", youtubeUrl, language, userId);
try
{
// Extrair ID do vídeo
string videoId = ExtractVideoId(youtubeUrl);
if (string.IsNullOrEmpty(videoId))
{
_logger.LogWarning("URL do YouTube inválida: {Url}", youtubeUrl);
throw new ArgumentException("URL do YouTube inválida");
}
// Verificar se já existe um resumo para este vídeo/usuário/idioma
bool exists = await _repository.ExistsAsync(videoId, userId, language);
if (exists)
{
_logger.LogInformation("Resumo já existente para vídeo: {VideoId}, usuário: {UserId}, idioma: {Language}",
videoId, userId, language);
return await _repository.GetByVideoIdAndUserIdAndLanguageAsync(videoId, userId, language);
}
// Criar novo resumo
var sessionId = Guid.NewGuid().ToString();
var summary = VideoSummary.Create(videoId, userId, language, sessionId);
// Salvar no repositório
await _repository.AddAsync(summary);
// Enviar para processamento via RabbitMQ
_logger.LogInformation("Enviando solicitação para processamento. SessionId: {SessionId}", sessionId);
await _sumarizerService.RequestVideoSummarization(sessionId, youtubeUrl, language);
return summary;
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao solicitar resumo de vídeo: {Message}", ex.Message);
throw;
}
}
public async Task<object> CheckSummaryStatusAsync(string id, string userId)
{
_logger.LogInformation("Verificando status do resumo. ID: {SummaryId}, usuário: {UserId}", id, userId);
var summary = await _repository.GetByIdAsync(id);
if (summary == null || summary.UserId != userId)
{
_logger.LogWarning("Resumo não encontrado ou acesso não autorizado. ID: {SummaryId}, UserId: {UserId}", id, userId);
return new { status = "NOT_FOUND" };
}
return new
{
status = summary.Status,
title = summary.Title,
thumbnailUrl = summary.ThumbnailUrl,
errorMessage = summary.ErrorMessage
};
}
private string ExtractVideoId(string url)
{
try
{
var uri = new Uri(url);
if (uri.Host.Contains("youtube.com"))
{
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
return query["v"];
}
else if (uri.Host.Contains("youtu.be"))
{
var segments = uri.Segments;
return segments[segments.Length - 1].TrimEnd('/');
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Erro ao extrair ID do vídeo da URL: {Url}", url);
}
return null;
}
}
}