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);
}
}