using adas_core.Domain.Models; using adas_core.Domain.Models.MongoModels; using adas_core.Domain.Models.Providers; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Serilog; namespace adas_core.Application.Providers; /// /// Represents an ADAS (Advanced Driver Assistance Systems) data provider that retrieves driver assistance observations through the shared infrastructure defined by . /// /// /// The constructor forwards the supplied of type and the of type to , ensuring consistent configuration and HTTP client management across all providers. /// /// public class AdasProvider(IOptions providerSettings, IHttpClientFactory httpClientFactory) : BaseProvider(providerSettings, httpClientFactory) { /* * Get observations of: * Predict of UCI stay duration * Predict of medications for patients */ /// /// Retrieves patient observations from the ADAS system, including stay duration predictions (most and less confident scenarios) and medication predictions. /// Logs an error and skips stay prediction observations if the prediction result is null or contains an error. /// Skips the medication prediction observation if no medication predictions are returned. /// /// The patient for whom observations are being calculated. /// A task that represents the asynchronous operation, returning a list of patient observations. /// public override async Task> GetObservations(Patient patient) { var calculatedObservations = new List(); //get data from two endpoints one from UCI stay another for medication var predictOfStay = await GetPredictOfStay(patient.PatientNumber); if (predictOfStay == null || predictOfStay.Result.ToLower().Contains("error")) Log.Error("Error retrieving predict of stay in ADAS result, message: {predictOfStay}", predictOfStay); else { var durationPredicted1 = predictOfStay.Payload.MaxBy(i => i.PercentageMin)!.Duration; var durationPredicted2 = predictOfStay.Payload.MinBy(i => i.PercentageMin)!.Duration; calculatedObservations.Add( new PatientObservation { PatientId = patient.Id, CodingSystem = "ADAS", Name = "Stay_Predict_Days_Most_Confident", //get the most confident interval to show the most probable scenario Value = durationPredicted1, Time = DateTime.UtcNow }); calculatedObservations.Add(new PatientObservation { PatientId = patient.Id, CodingSystem = "ADAS", Name = "Stay_Predict_Days_Less_Confident", //get the less confident interval to show the less probable scenario Value = durationPredicted2, Time = DateTime.UtcNow }); } var predictMedication = await GetPredictMedications(patient.PatientNumber); if (predictMedication != null && predictMedication.Any()) calculatedObservations.Add(new PatientObservation { PatientId = patient.Id, CodingSystem = "ADAS", Name = "Medication_Predict", Value = ParseAdasMedicationsToMedicationObservation(predictMedication), Time = DateTime.UtcNow }); return calculatedObservations; } /// /// Concatenates up to the first five ADAS medication prediction results into a single caret-delimited string for use as a medication observation value. /// /// The list of ADAS medication prediction results to be serialized. Only the first five entries are included. /// A string containing the selected medication prediction entries joined by the "^" delimiter. /// private static string ParseAdasMedicationsToMedicationObservation( List medicationPredict) { return string.Join("^", medicationPredict.Take(5)); } /// /// Retrieves the ADAS prediction of length of stay for the specified patient from an external service. /// Returns null if the patient number is null, if the service response is unsuccessful, or if an exception occurs during the request. /// /// The unique identifier of the patient whose ADAS stay prediction is being requested. /// A task containing the deserialized result on success, or null if the patient number is null, the response is unsuccessful, or the call throws. /// private async Task GetPredictOfStay(string? patientNumber) { if (patientNumber == null) { Log.Error("Error retrieving ADAS predict of stay patient number is null"); return null; } try { var client = GetClient(); var response = await client.GetAsync($"predictStay?patientNumber={patientNumber}"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(content); } Log.Error( "Error retrieving calculated ADAS observation length of stay for patient: {patientNumber}, status code: {response.StatusCode} ", patientNumber, response.StatusCode); return null; } catch (Exception e) { Log.Error("Exception retrieving ADAS predict of stay for patient: {patientNumber} exception: {e}", patientNumber, e.Message); return null; } } /// /// Retrieves the predicted medication needs for a given patient by calling the pharmacy prediction service. /// Returns null if the patient number is null, the service response is unsuccessful, or an exception occurs during the request. /// /// The unique identifier of the patient whose ADAS medication predictions are being retrieved. /// A task containing a list of with the predicted medication data, or null if the request fails or the patient number is null. /// private async Task?> GetPredictMedications(string? patientNumber) { if (patientNumber == null) { Log.Error("Error retrieving ADAS predict of stay for patient number is null"); return null; } try { var client = GetClient(); var response = await client.GetAsync($"predictMedicationNeedsPharmacy?patientNumber={patientNumber}"); if (response.IsSuccessStatusCode) { var content = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject>(content); } Log.Error( "Error retrieving calculated ADAS medicines for patient: {patientNumber}, status code: {response.StatusCode}", patientNumber, response.StatusCode); return null; } catch (Exception e) { Log.Error("Exception retrieving ADAS predict medicines for patient: {patientNumber} exception: {e}", patientNumber, e.Message); return null; } } /// /// Creates a new instance and configures it with the configured base address URL. /// /// An with its set to the configured Url. /// private HttpClient GetClient() { var client = HttpClientFactory.CreateClient(); client.BaseAddress = new Uri(Url); return client; } }