using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
namespace adas_core.Infrastructure.Repositories;
///
/// Represents a MongoDB-backed repository for documents, exposing pump alarm event-specific data access through the contract.
///
///
/// Inherits the generic MongoDB persistence capabilities of , specializing them for the entity type.
///
public class PumpAlarmEventRepository : MongoRepository, IPumpAlarmEventRepository
{
private readonly ApiSettings _apiSettings;
///
/// Initializes a new instance of the repository, capturing the configured from and forwarding to the base repository for persistence operations.
///
/// The wrapper that exposes the application's .
/// The passed to the base constructor and used to perform MongoDB operations.
///
public PumpAlarmEventRepository(IOptions apiSettings, IMongoDatabase database)
: base(database)
{
_apiSettings = apiSettings.Value;
}
///
/// Retrieves the collection name used for pump alarm events, returning the configured value from _apiSettings.PumpAlarmEvent when set, or falling back to the default "pump_alarm_event".
///
/// The configured pump alarm event collection name, or the default "pump_alarm_event" when no configuration value is available.
///
public override string GetCollectionName()
{
return _apiSettings.PumpAlarmEvent ?? "pump_alarm_event";
}
///
/// Creates the MongoDB indexes for the PumpAlarmEvent collection, optimizing the most common query patterns: device lookup with reverse-chronological time ordering, time-only range queries, patient lookup, and device queries filtered by alarm type.
///
///
public override async Task CreateIndexes()
{
var indexModels = new List>
{
// Principal para consultas por bomba y orden temporal
new(
Builders.IndexKeys
.Ascending(x => x.DeviceId)
.Descending(x => x.Time),
new CreateIndexOptions { Name = "ix_deviceId_time" }),
// Índice temporal
new(
Builders.IndexKeys.Descending(x => x.Time),
new CreateIndexOptions { Name = "ix_time" }),
// por paciente
new(
Builders.IndexKeys.Ascending(x => x.PatientId),
new CreateIndexOptions { Name = "ix_patientId" }),
//por tipo de alarma dentro de una bomba
new(
Builders.IndexKeys
.Ascending(x => x.DeviceId)
.Ascending(x => x.AlarmType),
new CreateIndexOptions { Name = "ix_device_alarmType" })
};
await Collection.Indexes.CreateManyAsync(indexModels);
}
///
/// Asynchronously inserts a new document into the underlying MongoDB collection.
///
/// The record to persist.
///
public async Task InsertAsync(PumpAlarmEvent alarmEvent)
{
await Collection.InsertOneAsync(alarmEvent);
}
public async Task> FindByDeviceIdAsync(string deviceId, DateTime? from = null,
DateTime? to = null, int? limit = null)
{
var filter = Builders.Filter.Eq(x => x.DeviceId, deviceId);
if (from.HasValue)
filter &= Builders.Filter.Gte(x => x.Time, from.Value);
if (to.HasValue)
filter &= Builders.Filter.Lte(x => x.Time, to.Value);
var find = Collection.Find(filter).SortByDescending(x => x.Time);
if (limit.HasValue) find = find.Limit(limit.Value) as IOrderedFindFluent;
return await find.ToListAsync();
}
///
/// Asynchronously retrieves the most recent for the device identified by , returning the entry with the latest time stamp, or null if no event exists.
///
/// The identifier of the device whose latest alarm event is being retrieved.
/// A that yields the latest associated with , or null if no matching event is found.
///
public async Task FindLastByDeviceIdAsync(string deviceId)
{
return await Collection
.Find(x => x.DeviceId == deviceId)
.SortByDescending(x => x.Time)
.FirstOrDefaultAsync();
}
///
/// Asynchronously removes all documents linked to the specified patient by deleting every record whose PatientId matches the supplied .
///
/// The of the patient whose associated documents should be deleted.
///
public async Task DeleteByPatientId(ObjectId patientId)
{
await Collection.DeleteManyAsync(x => x.PatientId == patientId);
}
///
/// Asynchronously updates the value of the specified field across multiple documents, replacing occurrences of with , and returns the number of documents that were modified.
///
/// The name of the field on whose value should be replaced.
/// The new value to assign to the field in matching documents.
/// The existing value used to identify documents to be updated.
/// The number of documents modified by the bulk update.
///
public async Task UpdateManyObjectIdByFiledNameAsync(string fieldName, ObjectId newId, ObjectId oldId)
{
var filter = Builders.Filter.Eq(fieldName, oldId);
var update = Builders.Update.Set(fieldName, newId);
var result = await Collection.UpdateManyAsync(filter, update);
return result.ModifiedCount;
}
}