using adas_core.Application.Repositories.Interfaces; using adas_core.Domain.Models; using adas_core.Domain.Models.AppSettings; using adas_core.Domain.Models.MongoModels; using Microsoft.Extensions.Options; using MongoDB.Bson; using MongoDB.Driver; using Serilog; using MongoUtils = adas_core.Infrastructure.Utils.MongoUtils; namespace adas_core.Infrastructure.Repositories; /// /// Represents a MongoDB-backed repository for entities, implementing the contract to provide data access operations. /// /// The type of the settings entity managed by the repository. public class PoCSettingsRepository : MongoRepository, IPoCSettingsRepository { private readonly ApiSettings _apiSettings; public PoCSettingsRepository(IOptions apiSettings, IMongoDatabase database) : base(database) { if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings)); _apiSettings = apiSettings.Value; } /// /// Retrieves the collection name used for Proof of Concept (PoC) settings, returning the value from the API settings or the default "poc_settings" when no value is configured. /// /// The configured PoC settings collection name, or "poc_settings" as a fallback when _apiSettings.PoCSettings is null. public override string GetCollectionName() { return _apiSettings.PoCSettings ?? "poc_settings"; } /// /// Deletes the PoCSettings document matching the specified identifier from the collection. /// /// The unique identifier of the PoCSettings document to delete. public async Task Delete(ObjectId id) { try { var filter = Builders.Filter.Eq(x => x.Id, id); await Collection.DeleteOneAsync(filter, null); } catch (Exception ex) { Log.Error("Error deleting PoCSettings by id: {id}. Exception: {ex}", id, ex); throw; } } /// /// Retrieves all PoCSettings records from the collection. /// If an error occurs during the retrieval, the exception is logged and an empty list is returned as a fallback. /// /// A task that represents the asynchronous operation. The task result contains a list of all PoCSettings records, or an empty list if an error occurs. public async Task> FindAll() { try { return (await Collection.FindAsync(Builders.Filter.Empty)).ToList(); } catch (Exception ex) { Log.Error("Error searching PoCSettings. Exception: {ex}", ex); return []; } } /// /// Retrieves a document from the collection by its unique identifier. /// Returns null when no matching document is found or when an error occurs while querying the database. /// /// The used to locate the PoCSettings document. /// A task that represents the asynchronous operation. The task result contains the matching or null if not found. public async Task FindById(ObjectId id) { try { var filter = Builders.Filter.Eq(p => p.Id, id); var result = await Collection.FindAsync(filter); return await result.FirstOrDefaultAsync(); } catch (Exception ex) { Log.Error("Error searching PoCSettings by id: {id}. Exception: {ex}", id, ex); return null; } } /// /// Retrieves the first PoCSettings record from the collection where the PatientLocation property is not null. /// /// The patient location provided as search criteria. Detailed attribute-based filtering by location fields is currently commented out. /// The first matching PoCSettings record, or null if no record is found. public async Task FindByLocation(PatientLocation location) { try { var filterBuilder = Builders.Filter; var filter = filterBuilder.Ne(p => p.PatientLocation, null); // TODO // if (!string.IsNullOrEmpty(location.PointOfCare) && !string.IsNullOrEmpty(location.Bed)) // { // filter = filterBuilder.And( // filter, // filterBuilder.Eq(p => p.PatientLocation!.PointOfCare, location.PointOfCare), // filterBuilder.Eq(p => p.PatientLocation!.Bed, location.Bed) // ); // } var result = await Collection.Find(filter).Limit(1).FirstOrDefaultAsync(); return result; } catch (Exception ex) { Log.Debug("Error searching by location. Exception: {ex}", ex); throw; } } /// /// Updates the existing PoC (Proof of Concept) settings asynchronously. If the update fails, the exception is logged and rethrown to the caller. /// /// The PoC settings entity to be updated, identified by its Id. public async Task Update(PoCSettings pocSettings) { try { await UpdateOneAsync(pocSettings.Id, pocSettings); } catch (Exception ex) { Log.Debug("Error updating PoC Settings: {pocS}. Exception: {ex}", pocSettings.ToString(), ex); throw; } } /// /// Creates the MongoDB indexes required for the collection, applying non-unique background indexing on the patientLocation field. /// public override async Task CreateIndexes() { var options = new CreateIndexOptions { Background = true, Unique = false }; //var optionsUq = new CreateIndexOptions() //{ // Background = true, // Unique = true, // PartialFilterExpression = Builders.Filter.Exists(p => p.PatientLocation) & // Builders.Filter.Exists(p => p.ManualRelayStatus) //}; var indexes = new List> { new("{ patientLocation: 1 }", options) //new("{ relayStatus: 1, bed: 1 }", optionsUq) }; await MongoUtils.EnsureIndexes(Collection, indexes); } }