using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using MongoDB.Driver.Core.Connections; using xCommons.Extensions; using xExceptions.Constants; using xFileService.Interfaces; using xFileService.Models.Dtos; using xFileService.Models.Entities; using xIdentityModels.Models; using xModels.Dtos; using XFileDto = xFileService.Models.Dtos.XFileDto; namespace xFileService.Providers { public abstract class XBaseFileProvider : IXBaseFileProvider { // #region Props ... /// /// Specified Provider ... /// public string ProvidedFor { get; } /// /// Specified Provider Repositroy ... /// public IXFileProvider Provider { get; } #endregion // #region Constructor ... public XBaseFileProvider( string providedFor, IXFileProvider provider ) { // Provider = provider; ProvidedFor = providedFor; } #endregion // #region Helper ... /// /// Get Specified Identifier ... /// /// /// public string GetIdentifier(TKey forProvidedId) { // return Provider.GetIdentifier( providedFor: ProvidedFor, forProvidedId: forProvidedId ); } #endregion // #region Tools ... /// /// Stream Specified File ... /// /// /// public async Task Stream(Guid id) { // // Check Validation and Owning ... var isValid = await IsOwned(id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Stream(id); return result; } /// /// Stream Specified File ... /// /// /// public async Task Stream(string fileName) { // // Validate ... var isValid = !fileName.IsNullOrEmpty(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Retrieve Dto and also Checking Owned ... var dto = await GetDto(fileName); isValid = !dto.IsNullOrDefault(); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Stream(fileName); return result; } /// /// Download Specified File ... /// /// /// public async Task Download(Guid id) { // // Validate ... var isValid = await IsOwned(id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Download(id); return result; } /// /// Download Specified File ... /// /// /// public async Task Download(string fileName) { // // Validate ... var isValid = !fileName.IsNullOrEmpty(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Retrieve Dto and also Checking Owned ... var dto = await GetDto(fileName); isValid = !dto.IsNullOrDefault(); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Download(fileName); return result; } /// /// Upload Files ... /// /// /// /// /// /// public async Task> Upload( TKey forProvidedId, IFormFileCollection files, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Validate ... var isValid = !forProvidedId.IsNull(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Here we are Following Custom Senario ... var dtos = await Provider.Upload( files: files, userInfo: userInfo, connectionId: connectionId ); // // Validate Dtos ... isValid = !dtos.IsNull() && dtos.HasChild(); if (isValid) { // foreach (var dto in dtos) { // await AddReference( id: dto.Id, userInfo: userInfo, forProvidedId: forProvidedId ); } } // var result = new List(); // isValid = !dtos.IsNull() && dtos.HasChild(); if (isValid) { // foreach (var dto in dtos) { // var idto = await Provider.Get(dto.Id); isValid = !idto.IsNullOrDefault() && await IsOwned(idto.Id); if (isValid) { result.Add(idto); } } } // return result; } /// /// Remove Specified Files ... /// /// /// /// /// /// public async Task> Remove( TKey forProvidedId, string ids = null, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // // Validate ... var isValid = userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // if ids Provided, Find all id's Specified Dtos ... // if not, gell all models which Owned and has Reference to forProvidedId ... var dtos = await GetAll(); if (!forProvidedId.IsNull()) { // var identifier = GetIdentifier(forProvidedId); dtos = dtos .Where(e => e.References.Any(er => er.ToNormalString() == identifier.ToNormalString())); } // // Filter Provided IDS ... if (!ids.IsNullOrEmpty()) { // var idsList = ids.ParseListGuid(); dtos = dtos.Where(d => !idsList.Contains(d.Id)); } // var result = new List(); isValid = !dtos.IsNullOrDefault() && dtos.HasChild(); if (isValid) { // foreach (var dto in dtos) { // var dtoIds = new List { dto.Id.ToString() }.ToListString(); var removeIds = await Provider.Remove(dtoIds, userInfo, connectionId); isValid = !removeIds.IsNull() && removeIds.HasChild() && removeIds.Contains(dto.Id); if (isValid) { result.Add(dto.Id); } } } // return result; } /// /// Retrieve Specified File Streaming Info ... /// /// /// public async Task GetFileDescriptor(Guid id) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Check Owned ... isValid = await IsOwned(id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.GetFileDescriptor(id); return result; } /// /// Retrieve Specified File Streaming Info ... /// /// /// public async Task GetFileDescriptor(string fileName) { // // Validate ... var isValid = !fileName.IsNullOrEmpty(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Check Owned ... var dto = GetDto(fileName); isValid = !dto.IsNullOrDefault(); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.GetFileDescriptor(fileName); return result; } #endregion // #region Data Model ... /// /// Get Specified File Model ... /// /// /// public async Task Get( Guid id ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Check Owned ... isValid = await IsOwned(id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Get(id); return result; } /// /// Get All Exists File Models ... /// /// public async Task> GetAll() { // var result = await Provider .FindMany(e => e.References.ToNormalString().Contains(ProvidedFor.ToNormalString())); return result; } /// /// Get All Exists File Models ... /// /// /// public async Task> GetAllFor(TKey forProvidedId) { // // Validate ... if (forProvidedId.IsNull()) { XException.InvalidArgs.Throw(); } // var identifier = GetIdentifier(forProvidedId); var result = await Provider .FindMany(e => e.References.ToNormalString().Contains(identifier.ToNormalString())); return result; } /// /// find an Entity by providing a Conditional Expression ... /// /// public async Task FindOne(Expression> whereClause) { // // Validate ... if (whereClause.IsNull()) { XException.InvalidArgs.Throw(); } // var whereFunc = whereClause.Compile(); var result = await Provider .FindOne(e => whereFunc(e) && e.References.ToNormalString().Contains(ProvidedFor.ToNormalString())); return result; } /// /// find a collection of Entities by proving a Conditional Expression ... /// /// /// public async Task> FindMany( Expression> whereClause ) { // // Validate ... if (whereClause.IsNull()) { XException.InvalidArgs.Throw(); } // var whereFunc = whereClause.Compile(); var result = await Provider .FindMany(e => whereFunc(e) && e.References.ToNormalString().Contains(ProvidedFor.ToNormalString())); return result; } /// /// retrieve Entities based on XQuery Pagination structure ... /// /// /// public async Task> Query( XQuery query ) { // // Define Owning Conditions ... Expression> whereClause = e => e.References .ToNormalString() .Contains(ProvidedFor.ToNormalString()); // var result = await Provider.ConditionalQuery( query: query, whereClause: whereClause ); return result; } /// /// retrieve Entities based on XQuery Pagination structure by providing a Conditional Expression ... /// /// /// /// public async Task> ConditionalQuery( Expression> whereClause, XQuery query ) { // // Validate ... if (whereClause.IsNull()) { XException.InvalidArgs.Throw(); } // // Prepare a Combination Where Condition ... var whereFunc = whereClause.Compile(); Expression> condition = e => whereFunc(e) && e.References.ToNormalString().Contains(ProvidedFor.ToNormalString()); // var result = await Provider.ConditionalQuery( query: query, whereClause: condition ); return result; } /// /// Update an Entity values ... /// /// /// /// /// public async Task Update( Guid id, XFileDto item, XUserClaimsInfoDto userInfo = null ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid() && !item.IsNullOrDefault() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Validate Own ... isValid = await IsOwned(item.Id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Update(item.Id, item, userInfo); return result; } /// /// remove an Entity ... /// /// /// /// public async Task Remove( Guid id, XUserClaimsInfoDto userInfo = null ) { // // Validate ... var isValid = !id.IsNull() && !id.IsDefaultGuid() && !userInfo.IsNullOrDefault(); if (!isValid) { XException.InvalidArgs.Throw(); } // // Validate Owned ... isValid = await IsOwned(id); if (!isValid) { XException.NotAllowed.Throw(); } // var result = await Provider.Remove(id, userInfo); return result; } /// /// count all exists Entities ... /// /// public async Task Count() { // var result = (await GetAll()).Count(); return result; } /// /// Check an Entity exists or not ... /// /// /// public async Task IsExists( Guid id ) { // var result = await IsOwned(id); return result; } #endregion // #region Private ... /// /// Check Specified Dto is Has Reference to Provider ... /// /// /// private async Task IsOwned(Guid id) { // // Validate ... var result = !id.IsNull() && !id.IsDefaultGuid(); if (!result) { XException.InvalidArgs.Throw(); } // // Check Exists ... result = await Provider.IsExists(id); if (!result) { XException.NotFound.Throw(); } // // Retrieve Dto ... var dto = await Provider.Get(id); result = !dto.IsNullOrDefault(); if (!result) { XException.ActionFailed.Throw(); } // result = !dto.References.IsNull() && dto.References.HasChild() && dto.References.Any(r => r.ToNormalString().Contains(ProvidedFor.ToNormalString())); // return result; } /// /// Get Specified Owned Dto by File Name ... /// /// /// private async Task GetDto(string fileName) { // XFileDto result = null; // if (!fileName.IsNullOrEmpty()) { // try { // result = await Provider.FindOne(d => d.Name == fileName || d.Thumb == fileName || d.FileName == fileName || d.Path.Contains(fileName) || d.ThumbPath.Contains(fileName) ); if (!result.IsNullOrDefault()) { // // Check Owning ... var isOwned = await IsOwned(result.Id); if (!isOwned) { result = null; } } } catch { } } // return result; } /// /// Get Specified Provided ID's Related Files ... /// /// /// private async Task> GetDtos(TKey forProvidedId) { // var result = new List(); // var identifier = GetIdentifier(forProvidedId); if (!forProvidedId.IsNull()) { // result = (await Provider .FindMany(e => e.References.ToNormalString().Contains(identifier.ToNormalString()))) .ToList(); } // return result; } /// /// Check Specified File has Refernce to Provider ... /// /// /// /// private async Task IsProvidedFor( TKey forProvidedId, Guid id ) { // var result = await Provider.IsProvidedFor( id: id, providedFor: ProvidedFor, forProvidedId: forProvidedId ); // return result; } /// /// Add Specified Reference to Specified File ... /// /// /// /// /// /// private async Task AddReference( TKey forProvidedId, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // await Provider.AddReference( id: id, userInfo: userInfo, providedFor: ProvidedFor, connectionId: connectionId, forProvidedId: forProvidedId ); } /// /// Remove Specified Reference from Specified File ... /// /// /// /// /// private async Task RemoveReference( TKey forProvidedId, Guid id, XUserClaimsInfoDto userInfo = null, string connectionId = null ) { // await Provider.RemoveReference( id: id, userInfo: userInfo, providedFor: ProvidedFor, connectionId: connectionId, forProvidedId: forProvidedId ); } #endregion } }