using AutoMapper; using FileService.Application.Ports; using FileService.Application.StorageContracts; using FileService.Domain.Entities; using FileService.Domain.IReposities; using IM.Commons; using IM.InitCommon; using MassTransit.Internals; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FileService.Application.UploadFileTask { public class UploadFileTaskService(IUploadTaskReposity reposity, IMapper mapper, IObjectStorageRouter router, IOptions options, IStorageRedisCache redis) { private readonly IUploadTaskReposity reposity = reposity; private readonly IMapper mapper = mapper; private readonly IObjectStorageRouter router = router; private readonly IOptions options = options; private readonly IStorageRedisCache redis = redis; private readonly IObjectStoragePort storage = router.Route(options.Value.DefaultProviderCode); public async Task> InitTaskAsync(UploadTaskInitCommand command) { CancellationToken cancellationToken = CancellationToken.None; var task = command.ToUploadTask(); var storageOption = options.Value.Providers[options.Value.DefaultProviderCode]; var storage = router.Route(storageOption.ProviderCode); var initRes = await storage.InitUploadAsync(new StorageContracts.InitiateUploadCommand( ProviderCode: options.Value.ProviderCode, Bucket: options.Value.Bucket, ObjectKey: options.Value.Endpoint, ContentType:task.ContentType.Value, ContentLength: command.FileSize, null ), cancellationToken); var res = mapper.Map(initRes); res.TaskId = task.Id; reposity.Create(task); await redis.SetAsync(new StorageContracts.UploadRuntimeCache( taskId: task.Id.ToString(), providerCode: storage.ProviderCode, uploadSessionId: res.UploadSessionId, bucket: storageOption.Bucket, region: storageOption.Region, objectKey: storageOption.Endpoint, fileSize: task.FileSize, totalPartCount: (int)(task.FileSize % storageOption.DefaultPartSizeBytes > 0 ? (task.FileSize / storageOption.DefaultPartSizeBytes) + 1 : task.FileSize / storageOption.DefaultPartSizeBytes) )); return Result.Success(res); } public async Task> GenerateUrlAsync(string sessionId, int partNum, Guid userId, CancellationToken token = default) { var taskCache = await redis.GetAsync(sessionId); if(taskCache is null) { return Result.Fail(ResultCode.CHUNK_NOT_FOUND); } var presignUrl = await storage.GenerateUploadUrlAsync(new GenerateUploadUrlCommand( ProviderCode: taskCache.ProviderCode, Bucket: taskCache.Bucket, ObjectKey: taskCache.ObjectKey, UploadSessionId: taskCache.UploadSessionId, PartNumber: partNum, ExpiresIn: options.Value.Providers[options.Value.DefaultProviderCode].UploadUrlExpiresIn ), token); return Result.Success(presignUrl); } //public async Task> CompleteTaskAsync() //{ // var taskCache = await redis.GetAsync() //} } }