205 lines
9.2 KiB
C#

using System.Text.Json;
using gehGassiApp.Core.Interfaces;
using gehGassiApp.Domain.Common;
using Microsoft.Extensions.Caching.Memory;
namespace gehGassiApp.Core.Services
{
/// <summary>
/// Service der den Umgang mit Ländern vereinfacht
/// </summary>
public class CountryService : ICountryService
{
private readonly IMemoryCache _memoryCache;
public CountryService()
{
_memoryCache = new MemoryCache(new MemoryCacheOptions(){});
}
/// <summary>
/// Initialisieren der Länder-Daten
/// </summary>
/// <returns>Task</returns>
private async Task InitAsync()
{
//Englisch
await using var streamEn = await FileSystem.OpenAppPackageFileAsync("countries/en/world.json");
using var readerEn = new StreamReader(streamEn);
var jsonEn = await readerEn.ReadToEndAsync();
_memoryCache.Set("Countries_EN", jsonEn);
//Deutsch
await using var streamDe = await FileSystem.OpenAppPackageFileAsync("countries/de/world.json");
using var readerDe = new StreamReader(streamDe);
var jsonDe = await readerDe.ReadToEndAsync();
_memoryCache.Set("Countries_DE", jsonDe);
//Bundesländer
await using var streamStates = await FileSystem.OpenAppPackageFileAsync("countries/subdivisions.json");
using var readerStates = new StreamReader(streamStates);
var jsonStates = await readerStates.ReadToEndAsync();
_memoryCache.Set("States", jsonStates);
}
/// <summary>
/// Gibt eine Liste aller Länder zurück
/// </summary>
/// <returns>Liste</returns>
public async Task<List<Country>> GetCountriesAsync()
{
var dummy = _memoryCache.Get<string>("Countries_EN");
if (string.IsNullOrWhiteSpace(dummy))
await InitAsync();
var countriesJson = _memoryCache.Get<string>("Countries_" + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToUpper());
if (string.IsNullOrWhiteSpace(countriesJson))
countriesJson = _memoryCache.Get<string>("Countries_EN");
var countries = JsonSerializer.Deserialize<List<Country>>(countriesJson);
countries.ForEach(c => c.Iso2 = c.Iso2.ToUpper());
return (countries ?? throw new InvalidOperationException()).OrderBy(c => c.Name).ToList();
}
/// <summary>
/// Gibt ein Land anhand des Codes zurück
/// </summary>
/// <param name="countryCode">ISO2</param>
/// <returns>Land oder null, wenn nicht gefunden</returns>
public async Task<Country> GetCountryAsync(string countryCode)
{
var country = (await GetCountriesAsync()).FirstOrDefault(c => String.Equals(c.Iso2, countryCode, StringComparison.CurrentCultureIgnoreCase));
return country;
}
/// <summary>
/// Gibt eine Liste von Bundesländern zurück
/// </summary>
/// <returns>Liste von Bundesländern</returns>
public async Task<List<State>> GetStatesAsync()
{
var statesJson = _memoryCache.Get<string>("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
await InitAsync();
statesJson = _memoryCache.Get<string>("States");
}
var states = JsonSerializer.Deserialize<List<State>>(statesJson);
return states;
}
/// <summary>
/// Gibt eine Liste von Bundesländern / Staaten eines Landes zurück
/// </summary>
/// <param name="countryCode">ISO2 des Landes</param>
/// <returns>Liste von Bundesländern</returns>
public async Task<List<State>> GetStatesAsync(string countryCode)
{
if (string.IsNullOrWhiteSpace(countryCode))
countryCode = "";
var statesJson = _memoryCache.Get<string>("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
await InitAsync();
statesJson = _memoryCache.Get<string>("States");
}
var states = JsonSerializer.Deserialize<List<State>>(statesJson);
return states != null ? states.Where(c => c.Iso2 == countryCode.ToUpper()).OrderBy(c => c.Name).ToList() : new List<State>();
}
/// <summary>
/// Gibt ein Bundesland / Staat eines Landes zurück
/// </summary>
/// <param name="countryCode">ISO2 des Landes</param>
/// <param name="stateCode">Code des Bundeslandes</param>
/// <returns>Bundesland oder null, wenn nicht gefunden</returns>
public async Task<State> GetStateAsync(string countryCode, string stateCode)
{
var states = await GetStatesAsync(countryCode);
return states.FirstOrDefault(c => c.Code == stateCode);
}
/// <summary>
/// Gibt ein Bundesland / Staat eines Landes zurück
/// </summary>
/// <param name="countryCode">ISO2 des Landes</param>
/// <param name="stateName">Name des Bundeslandes</param>
/// <returns>Bundesland oder null, wenn nicht gefunden</returns>
public async Task<State> GetStateByNameAsync(string countryCode, string stateName)
{
var states = await GetStatesAsync(countryCode);
return states.FirstOrDefault(c => c.Name.ToLowerInvariant() == stateName.ToLowerInvariant());
}
/// <summary>
/// Gibt eine Liste der Ländercodes zurück die zu einem Filter passen
/// </summary>
/// <param name="filter">Filter</param>
/// <param name="operatorValue">Operator der angewendet werden soll</param>
/// <returns>Liste gefundener Ländercodes</returns>
public async Task<List<string>> FindCountryCodesAsync(string filter, string operatorValue)
{
var countries = await GetCountriesAsync();
if (operatorValue == "equals")
return (from country in countries where country.Name.ToLower().Equals(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "notequals")
return (from country in countries where country.Name.ToLower().Equals(filter.ToLower()) == false select country.Iso2).ToList();
if (operatorValue == "startswith")
return (from country in countries where country.Name.ToLower().StartsWith(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "endswith")
return (from country in countries where country.Name.ToLower().EndsWith(filter.ToLower()) select country.Iso2).ToList();
if (operatorValue == "contains")
return (from country in countries where country.Name.ToLower().Contains(filter.ToLower()) select country.Iso2).ToList();
return new List<string>();
}
/// <summary>
/// Gibt eine Liste der Bundesland-Codes zurück die zu einem Filter passen
/// </summary>
/// <param name="filter">Filter</param>
/// <param name="operatorValue">Operator der angewendet werden soll</param>
/// <returns>Liste gefundener Bundeslandcodes</returns>
public async Task<List<string>> FindStateCodesAsync(string filter, string operatorValue)
{
var states = await GetStatesAsync();
if (operatorValue == "equals")
return (from state in states where state.Name.ToLower().Equals(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "notequals")
return (from state in states where state.Name.ToLower().Equals(filter.ToLower()) == false select state.Code).ToList();
if (operatorValue == "startswith")
return (from state in states where state.Name.ToLower().StartsWith(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "endswith")
return (from state in states where state.Name.ToLower().EndsWith(filter.ToLower()) select state.Code).ToList();
if (operatorValue == "contains")
return (from state in states where state.Name.ToLower().Contains(filter.ToLower()) select state.Code).ToList();
return new List<string>();
}
/// <summary>
/// Gibt eine Liste aller Länder zurück die in der Nationalitätenliste enthalten sind
/// </summary>
/// <returns>Liste</returns>
public async Task<List<Country>> GetNationalitiesAsync()
{
var currentLanguage = "EN";
if(Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToLower() == "de")
currentLanguage = "DE";
await using var stream = await FileSystem.OpenAppPackageFileAsync($"countries/{currentLanguage.ToLower()}/nationalities.json");
using var reader = new StreamReader(stream);
var json = await reader.ReadToEndAsync();
var countries = JsonSerializer.Deserialize<List<Country>>(json);
countries.ForEach(c => c.Iso2 = c.Iso2.ToUpper());
return (countries ?? throw new InvalidOperationException()).OrderBy(c => c.Name).ToList();
}
}
}