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 { /// /// Provides a repository implementation for entities backed by a MongoDB data store. /// /// Inherits base functionality from and implements the contract. public class PumpStateRepository : MongoRepository, IPumpStateRepository { private readonly ApiSettings _apiSettings; public PumpStateRepository(IOptions apiSettings, IMongoDatabase database) : base(database) { _apiSettings = apiSettings.Value; } /// /// Retrieves the collection name for pump states, returning the configured value from API settings or the default name "pump_states" when the setting is not provided. /// /// The configured pump states collection name, or the default value "pump_states" if the setting is null. public override string GetCollectionName() { return _apiSettings.PumpStates ?? "pump_states"; } public override async Task CreateIndexes() { var indexModels = new List> { // Clave única del snapshot new CreateIndexModel( Builders.IndexKeys.Ascending(x => x.DeviceId), new CreateIndexOptions { Unique = true, Name = "ux_deviceId" }), // Consultas por DeviceId + actualización temporal new CreateIndexModel( Builders.IndexKeys .Ascending(x => x.DeviceId) .Descending(x => x.LastUpdated), new CreateIndexOptions { Name = "ix_deviceId_lastUpdated" }), // indexado por PatientId new CreateIndexModel( Builders.IndexKeys.Ascending(x => x.PatientId), new CreateIndexOptions { Name = "ix_patientId" }) }; await Collection.Indexes.CreateManyAsync(indexModels); } /// /// Retrieves the pump state associated with the specified device identifier, returning null when no matching record exists. /// /// The unique identifier of the device whose pump state should be looked up. /// A instance if a matching record is found; otherwise, null. public async Task FindByDeviceIdAsync(string deviceId) { return await Collection.Find(x => x.DeviceId == deviceId).FirstOrDefaultAsync(); } /// /// Inserts the specified or updates the existing one identified by its DeviceId. If a matching record is found, its identifier is reused; otherwise a new identifier is generated when the provided one is empty. /// /// The pump state to persist. Its Id is preserved or assigned based on whether a record with the same DeviceId already exists. public async Task UpsertAsync(PumpState state) { var existing = await Collection .Find(x => x.DeviceId == state.DeviceId) .FirstOrDefaultAsync(); if (existing != null) state.Id = existing.Id; else if (state.Id == ObjectId.Empty) state.Id = ObjectId.GenerateNewId(); await Collection.ReplaceOneAsync( x => x.DeviceId == state.DeviceId, state, new ReplaceOptions { IsUpsert = true }); } /// /// Asynchronously retrieves all records from the data store. /// /// A task that represents the asynchronous operation, containing an of all records; an empty collection is returned if no records exist. public async Task> GetAllAsync() { return await Collection.Find(Builders.Filter.Empty).ToListAsync(); } } }