using System.Text; using System.Text.Json; using MesaFabApproval.Shared.Models; using Microsoft.Extensions.Caching.Memory; using MudBlazor; namespace MesaFabApproval.Client.Services; public interface IPCRBService { Task IdIsValid(string id); Task> GetAllPCRBs(bool bypassCache); Task CreateNewPCRB(PCRB pcrb); Task GetPCRBByPlanNumber(int planNumber, bool bypassCache); Task GetPCRBByTitle(string title, bool bypassCache); Task UpdatePCRB(PCRB pcrb); Task DeletePCRB(int planNumber); } public class PCRBService : IPCRBService { private readonly IMemoryCache _cache; private readonly IHttpClientFactory _httpClientFactory; private readonly ISnackbar _snackbar; public PCRBService(IMemoryCache cache, IHttpClientFactory httpClientFactory, ISnackbar snackbar) { _cache = cache ?? throw new ArgumentNullException("IMemoryCache not injected"); _httpClientFactory = httpClientFactory ?? throw new ArgumentNullException("IHttpClientFactory not injected"); _snackbar = snackbar ?? throw new ArgumentNullException("ISnackbar not injected"); } public async Task IdIsValid(string id) { bool isMatch = true; if (string.IsNullOrWhiteSpace(id)) isMatch = false; try { HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/getByPlanNumber?planNumber={id}"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (responseMessage.IsSuccessStatusCode) { string responseContent = await responseMessage.Content.ReadAsStringAsync(); JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; PCRB? pcrb = JsonSerializer.Deserialize(responseContent, jsonSerializerOptions); if (pcrb is null) isMatch = false; } else { isMatch = false; } } catch (Exception) { isMatch = false; } if (!isMatch) return $"{id} is not a valid PCRB#"; return null; } public async Task> GetAllPCRBs(bool bypassCache) { try { IEnumerable? allPCRBs = null; if (!bypassCache) allPCRBs = _cache.Get>("allPCRBs"); if (allPCRBs is null) { HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/all?bypassCache={bypassCache}"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (responseMessage.IsSuccessStatusCode) { string responseContent = await responseMessage.Content.ReadAsStringAsync(); JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; allPCRBs = JsonSerializer.Deserialize>(responseContent, jsonSerializerOptions) ?? throw new Exception("Unable to parse PCRBs from API response"); _cache.Set($"allPCRBs", allPCRBs, DateTimeOffset.Now.AddMinutes(15)); } else { throw new Exception(responseMessage.ReasonPhrase); } } return allPCRBs; } catch (Exception) { throw; } } public async Task CreateNewPCRB(PCRB pcrb) { if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb"); requestMessage.Content = new StringContent(JsonSerializer.Serialize(pcrb), Encoding.UTF8, "application/json"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); PCRB newPCRB = await GetPCRBByTitle(pcrb.Title, true); _cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); IEnumerable? allPCRBs = _cache.Get>("allPCRBs"); if (allPCRBs is not null) { List pcrbList = allPCRBs.ToList(); pcrbList.Add(newPCRB); _cache.Set("allPCRBs", pcrbList); } } public async Task GetPCRBByPlanNumber(int planNumber, bool bypassCache) { if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB plan #"); PCRB? pcrb = null; if (!bypassCache) pcrb = _cache.Get($"pcrb{planNumber}"); if (pcrb is null && !bypassCache) pcrb = _cache.Get>("allPCRBs")?.FirstOrDefault(m => m.PlanNumber == planNumber); if (pcrb is null) { HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/getByPlanNumber?planNumber={planNumber}&bypassCache={bypassCache}"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); string responseContent = await responseMessage.Content.ReadAsStringAsync(); JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; pcrb = JsonSerializer.Deserialize(responseContent, jsonSerializerOptions) ?? throw new Exception("unable to parse PCRB from API response"); _cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); if (bypassCache) { IEnumerable? allPCRBs = _cache.Get>("allPCRBs"); if (allPCRBs is not null) { List pcrbList = allPCRBs.ToList(); pcrbList.RemoveAll(p => p.PlanNumber == planNumber); pcrbList.Add(pcrb); _cache.Set("allPCRBs", pcrbList); } } } return pcrb; } public async Task GetPCRBByTitle(string title, bool bypassCache) { if (string.IsNullOrWhiteSpace(title)) throw new ArgumentNullException("title cannot be null"); PCRB? pcrb = null; if (!bypassCache) pcrb = _cache.Get($"pcrb{title}"); if (pcrb is null && !bypassCache) pcrb = _cache.Get>("allPCRBs")?.FirstOrDefault(m => m.Title.Equals(title)); if (pcrb is null) { HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/getByTitle?title={title}&bypassCache={bypassCache}"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); string responseContent = await responseMessage.Content.ReadAsStringAsync(); JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true }; pcrb = JsonSerializer.Deserialize(responseContent, jsonSerializerOptions) ?? throw new Exception("unable to parse PCRB from API response"); _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); if (bypassCache) { IEnumerable? allPCRBs = _cache.Get>("allPCRBs"); if (allPCRBs is not null) { List pcrbList = allPCRBs.ToList(); pcrbList.RemoveAll(p => p.PlanNumber == pcrb.PlanNumber); pcrbList.Add(pcrb); _cache.Set("allPCRBs", pcrbList); } } } return pcrb; } public async Task UpdatePCRB(PCRB pcrb) { if (pcrb is null) throw new ArgumentNullException("MRB cannot be null"); HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb"); requestMessage.Content = new StringContent(JsonSerializer.Serialize(pcrb), Encoding.UTF8, "application/json"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); _cache.Set($"pcrb{pcrb.PlanNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); IEnumerable? allPCRBs = _cache.Get>("allPCRBs"); if (allPCRBs is not null) { List pcrbList = allPCRBs.ToList(); pcrbList.RemoveAll(m => m.PlanNumber == pcrb.PlanNumber); pcrbList.Add(pcrb); _cache.Set("allPCRBs", pcrbList); } } public async Task DeletePCRB(int planNumber) { if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB plan #"); HttpClient httpClient = _httpClientFactory.CreateClient("API"); HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/delete?planNumber={planNumber}"); HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); IEnumerable allPCRBs = await GetAllPCRBs(true); _cache.Set("allPCRBs", allPCRBs); } }