using adas_core.Application.Repositories.Interfaces;
using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoUtils = adas_core.Infrastructure.Utils.MongoUtils;
namespace adas_core.Infrastructure.Repositories;
///
/// Repository for managing patient diagnoses in a MongoDB collection. Provides methods for CRUD operations and querying diagnoses by patient ID and code.
///
public class DiagnosisRepository : MongoRepository, IDiagnosisRepository
{
private readonly ApiSettings _apiSettings;
///
/// Initializes a new instance of the class with the specified API settings and MongoDB database. The API settings are used to determine the collection name for storing patient diagnoses.
///
/// The API settings containing configuration for the repository.
/// The MongoDB database instance.
/// Thrown when the API settings are null.
public DiagnosisRepository(IOptions apiSettings, IMongoDatabase database) : base(database)
{
if (apiSettings == null) throw new ArgumentNullException(nameof(apiSettings));
_apiSettings = apiSettings.Value;
} //For testing
///
/// Gets the name of the MongoDB collection for storing patient diagnoses. The collection name is determined by the API settings, and defaults to "patients_diagnosis" if not specified.
///
/// The name of the MongoDB collection for patient diagnoses.
public override string GetCollectionName()
{
return _apiSettings.PatientsDiagnosis ?? "patients_diagnosis";
}
///
/// Retrieves a list of patient diagnoses for a given patient ID. The diagnoses are sorted in descending order by time, with the most recent diagnoses appearing first.
///
/// The ID of the patient whose diagnoses are to be retrieved.
/// A list of patient diagnoses for the specified patient ID.
public async Task> GetByPatient(ObjectId patientId)
{
var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId);
var result = await Collection.FindAsync(filter,
new FindOptions { Sort = Builders.Sort.Descending("time") });
return result.ToList();
}
///
/// Deletes a patient diagnosis by its ID. This method removes the diagnosis document from the MongoDB collection based on the provided ID.
///
/// The ID of the patient diagnosis to delete.
/// A task representing the asynchronous operation.
public new async Task DeleteAsync(ObjectId id)
{
var filter = Builders.Filter.Eq(t => t.Id, id);
await Collection.DeleteOneAsync(filter);
}
///
/// Inserts a new patient diagnosis into the MongoDB collection. This method adds a new diagnosis document to the collection based on the provided object.
///
/// The patient diagnosis to insert.
/// A task representing the asynchronous operation.
public override async Task InsertOneAsync(PatientDiagnosis diagnosis)
{
await Collection.InsertOneAsync(diagnosis);
}
///
/// Deletes all patient diagnoses associated with a specific patient ID. This method removes all diagnosis documents from the MongoDB collection that match the provided patient ID.
///
/// The ID of the patient whose diagnoses are to be deleted.
///
public async Task DeleteByPatientId(ObjectId patientId)
{
var filter = Builders.Filter.Eq(po => po.PatientId, patientId);
await Collection.DeleteManyAsync(filter);
}
///
/// Finds a patient diagnosis by patient ID, code, and coding system.
/// This method retrieves a single diagnosis document from the MongoDB collection that matches the provided patient ID, code, and coding system.
/// If no matching diagnosis is found, it returns null.
///
/// The ID of the patient.
/// The code of the diagnosis.
/// The coding system of the diagnosis.
/// The matching patient diagnosis, or null if not found.
public async Task FindByPatientIdAndCode(ObjectId patientId, string? code, string? codingSystem)
{
var builder = Builders.Filter;
var filter = builder.And(
builder.Eq(ob => ob.PatientId, patientId),
builder.Eq(ob => ob.Code, code),
builder.Eq(ob => ob.CodingSystem, codingSystem)
);
var result = await Collection.FindAsync(filter);
return await result.FirstOrDefaultAsync();
}
///
/// Finds patient diagnoses by patient ID. This method retrieves all diagnosis documents from the MongoDB collection that match the provided patient ID.
/// The results are returned as an asynchronous cursor, allowing for efficient retrieval of large datasets.
///
/// The ID of the patient whose diagnoses are to be retrieved.
/// An asynchronous cursor of patient diagnoses.
public async Task> FindByPatientIdAsync(ObjectId patientId)
{
var filter = Builders.Filter.Eq(ob => ob.PatientId, patientId);
return await Collection.FindAsync(filter);
}
///
/// Updates the patient ID for all diagnoses that match the old patient ID.
/// This method performs a bulk update operation on the MongoDB collection, changing the patient ID from the old value to the new value for all matching diagnosis documents.
///
/// The name ID associated with the patient.
/// The new patient ID to be set.
/// The old patient ID to be replaced.
/// A task representing the asynchronous operation.
public async Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId)
{
await UpdateManyObjectIdAsync(nameId, id, oldId);
}
///
/// Creates indexes for the patient diagnosis collection. This method ensures that the necessary indexes are created on the MongoDB collection to optimize query performance.
///
/// A task representing the asynchronous operation.
public override async Task CreateIndexes()
{
var options = new CreateIndexOptions { Background = true, Unique = false };
var indexes = new List>
{
new("{ patientid: 1 }", options)
};
await MongoUtils.EnsureIndexes(Collection, indexes);
}
}