using DomainResults.Common;
using DataProviders;
using DataProviders.Buckets;
using FileSecurityService;
using Core.Abstractions;
namespace WeatherForecast.Services {
  /// 
  /// 
  /// 
  public interface IFilesService {
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    (List?, IDomainResult) Post(Guid siteId, Guid userId, List files);
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    IDomainResult Delete(Guid siteId, Guid userId);
  }
  /// 
  /// 
  /// 
  public class FilesService : ServiceBase, IFilesService {
    private readonly IFileSecurityService _fileSecurityService;
    private readonly IImageBucketDataProvider _imageBucketDataProvider;
    /// 
    /// 
    /// 
    /// 
    /// 
    public FilesService(
      ILogger logger,
      IFileSecurityService fileSecurityService,
      IImageBucketDataProvider imageBucketDataProvider
    ) : base(logger) {
      _fileSecurityService = fileSecurityService;
      _imageBucketDataProvider = imageBucketDataProvider;
    }
    /// 
    /// Process uploaded files
    /// 
    /// 
    /// 
    /// 
    /// 
    public (List?, IDomainResult) Post(Guid siteId, Guid userId, List files) {
      try {
        // Don't rely on or trust the FileName property without validation.
        if(files.Any(x => !(x.Length > 0)))
          return IDomainResult.Failed?>();
        var newFiles = new List();
        foreach (var formFile in files) {
          using var ms = new MemoryStream();
          formFile.CopyTo(ms);
          var bytes = ms.ToArray();
          var (fileCategory, signatureResult) = _fileSecurityService.CheckFileSignature(formFile.FileName, bytes, formFile.ContentType);
          if (!signatureResult.IsSuccess || fileCategory == null)
            return IDomainResult.Failed?>();
          var bucketFile = new BucketFile(formFile.FileName, bytes, formFile.ContentType);
          newFiles.Add(bucketFile);
        }
        var (list, result) = _imageBucketDataProvider.UploadMany(siteId, userId, newFiles);
        if (!result.IsSuccess || list == null)
          return IDomainResult.Failed?>();
        return IDomainResult.Success(list);
      }
      catch (Exception ex) {
        _logger.LogError(ex, "Unhandled exception");
        return IDomainResult.Failed?> (ex.Message);
      }
    }
    /// 
    /// 
    /// 
    /// 
    /// 
    /// 
    public IDomainResult Delete(Guid siteId, Guid userId) {
      try {
        return _imageBucketDataProvider.DeletMany(siteId, userId);
      }
      catch (Exception ex) {
        _logger.LogError(ex, "Unhandled exception");
        return IDomainResult.Failed(ex.Message);
      }
    }
  }
}