using Microsoft.Extensions.Logging;

using DomainResults.Common;

using MongoDB.Driver;

using DataProviders.Abstractions;
using MongoDB.Driver.GridFS;

namespace DataProviders.Buckets {

  /// <summary>
  /// 
  /// </summary>
  public abstract class SpecificBucketDataProviderBase : BucketDataProviderBase {

    private readonly string _bucketName;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    /// <param name="client"></param>
    public SpecificBucketDataProviderBase(
      ILogger<BucketDataProviderBase> logger,
      IMongoClient client,
      string bucketName
    ) : base(logger, client) {
      _bucketName = bucketName;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="userId"></param>
    /// <param name="file"></param>
    /// <returns></returns>
    public (Guid?, IDomainResult) Upload(Guid siteId, Guid userId, BucketFile file) => Upload(siteId, userId, file, _bucketName);

    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="userId"></param>
    /// <param name="files"></param>
    /// <returns></returns>
    public (List<Guid>?, IDomainResult) UploadMany(Guid siteId, Guid userId, List<BucketFile> files) => UploadMany(siteId, userId, files, _bucketName);


    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="fileId"></param>
    /// <returns></returns>
    public (BucketFile?, IDomainResult) Download(Guid siteId, Guid fileId) {
      var filter = Builders<GridFSFileInfo>.Filter.And(
          Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
          Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["private"], false),
          Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
        );

      var (list, result) = Download(filter, _bucketName);

      if (!result.IsSuccess || list == null)
        return (null, result);

      return (list.First(), result);
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="userId"></param>
    /// <param name="fileId"></param>
    /// <returns></returns>
    public (BucketFile?, IDomainResult) Download(Guid siteId, Guid userId, Guid fileId) {

      var filter = Builders<GridFSFileInfo>.Filter.And(
        Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["siteId"], $"{siteId}"),
        Builders<GridFSFileInfo>.Filter.Eq(x => x.Metadata["userId"], $"{userId}"),
        Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, $"{fileId}")
      );

      var (list, result) = Download(filter, _bucketName);

      if (!result.IsSuccess || list == null)
        return (null, result);

      return (list.First(), result);
    }

      /// <summary>
      /// 
      /// </summary>
      /// <param name="siteId"></param>
      /// <param name="userId"></param>
      /// <param name="fileId"></param>
      /// <returns></returns>
      public IDomainResult DeleteOne(Guid siteId, Guid userId, Guid fileId) => DeleteOne(siteId, userId, fileId, _bucketName);

    /// <summary>
    /// 
    /// </summary>
    /// <param name="siteId"></param>
    /// <param name="userId"></param>
    /// <returns></returns>
    public IDomainResult DeletMany(Guid siteId, Guid userId) => DeleteMany(siteId, userId, _bucketName);
  }
}
