using adas_core.Application.Repositories.Interfaces; using adas_core.Application.Services.Interfaces; using adas_core.Domain.Models; using adas_core.Domain.Models.AppSettings; using adas_core.Domain.Models.MongoModels; using Microsoft.Extensions.Options; namespace adas_core.Application.Services; /// /// Provides a proof-of-concept implementation of the IPoCMappingService interface, /// delivering the mapping functionality defined by that contract. /// public class PoCMappingService : IPoCMappingService { private readonly string _key; private readonly bool _mappingRequired; private readonly IPoCMappingRepository _pocMappingRepository; private readonly int? _refreshTimeout; private PoCMapping? _mapping; private DateTime _nextRefresh = DateTime.MinValue; public PoCMappingService(IPoCMappingRepository pocMappingRepository, IOptions apiSettings) { _pocMappingRepository = pocMappingRepository; _refreshTimeout = apiSettings.Value.PointOfCareMapping?.Refresh; _mappingRequired = apiSettings.Value.PointOfCareMapping?.Required ?? _mappingRequired; _key = apiSettings.Value.PointOfCareMapping?.Key ?? "PV1"; } /// /// Maps a received location with bed and pointOfCare to the equivalence in the PocMapping table if it finds the value, /// otherwise it returns null /// /// location /// mapped location public async Task Map(PatientLocation original) { var pocMapping = await GetMapping(); var poc = pocMapping?.PointOfCares.FindAll(p => p.OriginalPoC == original.UnitName); var pocWithBed = poc?.FirstOrDefault(p => p.Beds.Any(bed => bed[0] == original.Bed)); var newBed = pocWithBed?.Beds.Where(bed => bed[0] == original.Bed).Select(bed => bed[1]).FirstOrDefault(); if (string.IsNullOrEmpty(newBed)) return _mappingRequired ? null : original; return new PatientLocation(pocWithBed!.NewPoC, newBed); } /// /// Return mapping from cache of database based on refreshTime /// /// private async Task GetMapping() { if (_mapping == null || DateTime.Now > _nextRefresh) { _mapping = await _pocMappingRepository.FindByKey(_key); _nextRefresh = _refreshTimeout.HasValue ? DateTime.Now.AddSeconds(_refreshTimeout.Value) : DateTime.MaxValue; } return _mapping; } }