using System.Text.Json;
using gehGassiApp.Core.Interfaces;
using gehGassiApp.Domain.Common;
using Microsoft.Extensions.Caching.Memory;
namespace gehGassiApp.Core.Services
{
///
/// Service der den Umgang mit Ländern vereinfacht
///
public class CountryService : ICountryService
{
private readonly IMemoryCache _memoryCache;
public CountryService()
{
_memoryCache = new MemoryCache(new MemoryCacheOptions(){});
}
///
/// Initialisieren der Länder-Daten
///
/// Task
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);
}
///
/// Gibt eine Liste aller Länder zurück
///
/// Liste
public async Task> GetCountriesAsync()
{
var dummy = _memoryCache.Get("Countries_EN");
if (string.IsNullOrWhiteSpace(dummy))
await InitAsync();
var countriesJson = _memoryCache.Get("Countries_" + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToUpper());
if (string.IsNullOrWhiteSpace(countriesJson))
countriesJson = _memoryCache.Get("Countries_EN");
var countries = JsonSerializer.Deserialize>(countriesJson);
countries.ForEach(c => c.Iso2 = c.Iso2.ToUpper());
return (countries ?? throw new InvalidOperationException()).OrderBy(c => c.Name).ToList();
}
///
/// Gibt ein Land anhand des Codes zurück
///
/// ISO2
/// Land oder null, wenn nicht gefunden
public async Task GetCountryAsync(string countryCode)
{
var country = (await GetCountriesAsync()).FirstOrDefault(c => String.Equals(c.Iso2, countryCode, StringComparison.CurrentCultureIgnoreCase));
return country;
}
///
/// Gibt eine Liste von Bundesländern zurück
///
/// Liste von Bundesländern
public async Task> GetStatesAsync()
{
var statesJson = _memoryCache.Get("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
await InitAsync();
statesJson = _memoryCache.Get("States");
}
var states = JsonSerializer.Deserialize>(statesJson);
return states;
}
///
/// Gibt eine Liste von Bundesländern / Staaten eines Landes zurück
///
/// ISO2 des Landes
/// Liste von Bundesländern
public async Task> GetStatesAsync(string countryCode)
{
if (string.IsNullOrWhiteSpace(countryCode))
countryCode = "";
var statesJson = _memoryCache.Get("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
await InitAsync();
statesJson = _memoryCache.Get("States");
}
var states = JsonSerializer.Deserialize>(statesJson);
return states != null ? states.Where(c => c.Iso2 == countryCode.ToUpper()).OrderBy(c => c.Name).ToList() : new List();
}
///
/// Gibt ein Bundesland / Staat eines Landes zurück
///
/// ISO2 des Landes
/// Code des Bundeslandes
/// Bundesland oder null, wenn nicht gefunden
public async Task GetStateAsync(string countryCode, string stateCode)
{
var states = await GetStatesAsync(countryCode);
return states.FirstOrDefault(c => c.Code == stateCode);
}
///
/// Gibt ein Bundesland / Staat eines Landes zurück
///
/// ISO2 des Landes
/// Name des Bundeslandes
/// Bundesland oder null, wenn nicht gefunden
public async Task GetStateByNameAsync(string countryCode, string stateName)
{
var states = await GetStatesAsync(countryCode);
return states.FirstOrDefault(c => c.Name.ToLowerInvariant() == stateName.ToLowerInvariant());
}
///
/// Gibt eine Liste der Ländercodes zurück die zu einem Filter passen
///
/// Filter
/// Operator der angewendet werden soll
/// Liste gefundener Ländercodes
public async Task> 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();
}
///
/// Gibt eine Liste der Bundesland-Codes zurück die zu einem Filter passen
///
/// Filter
/// Operator der angewendet werden soll
/// Liste gefundener Bundeslandcodes
public async Task> 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();
}
///
/// Gibt eine Liste aller Länder zurück die in der Nationalitätenliste enthalten sind
///
/// Liste
public async Task> 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>(json);
countries.ForEach(c => c.Iso2 = c.Iso2.ToUpper());
return (countries ?? throw new InvalidOperationException()).OrderBy(c => c.Name).ToList();
}
}
}