using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using gehGassi.Core.Services;
using gehGassi.Domain.Common;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace gehGassi.Web.Services
{
///
/// Service der den Umgang mit Ländern vereinfacht
///
public class CountryService : ICountryService
{
private readonly IDistributedCache _memoryCache;
private readonly IOptions _options;
private readonly IWebHostEnvironment _hostingEnvironment;
///
/// Erstellt eine Instanz
///
/// Instanz eines IDistributedCache
/// Instanz von CountryServiceOptions
/// Instanz eines IHostingEnvironment
public CountryService(IDistributedCache memoryCache, IOptions options, IWebHostEnvironment hostingEnvironment)
{
_memoryCache = memoryCache;
_options = options;
_hostingEnvironment = hostingEnvironment;
Init();
}
///
/// Initialisiert den Service
///
private void Init()
{
var path = Path.Combine(_hostingEnvironment.WebRootPath, _options.Value.Directory);
foreach (var language in _options.Value.Languages)
{
var countryFile = Path.Combine(path + "\\" + language + "\\world.json");
if (File.Exists(countryFile))
{
var json = File.ReadAllText(countryFile);
var countries = JsonConvert.DeserializeObject>(json);
var options = new DistributedCacheEntryOptions();
options.SetSlidingExpiration(TimeSpan.FromMinutes(15));
var jsonString = JsonSerializer.Serialize(countries);
_memoryCache.SetString("Countries_" + language.ToUpper(), jsonString, options);
}
}
//Bundesländer laden
var subdivisionFile = Path.Combine(path + "\\subdivisions.json");
if (File.Exists(subdivisionFile))
{
var json = File.ReadAllText(subdivisionFile);
var subdivisions = JsonConvert.DeserializeObject>(json);
var options = new DistributedCacheEntryOptions();
options.SetSlidingExpiration(TimeSpan.FromMinutes(15));
var jsonString = JsonSerializer.Serialize(subdivisions);
_memoryCache.SetString("States", jsonString, options);
}
}
///
/// Gibt eine Liste aller Länder zurück
///
/// Liste
public List GetCountries()
{
var dummy = _memoryCache.GetString("Countries_EN");
if (string.IsNullOrWhiteSpace(dummy))
Init();
var countriesJson = _memoryCache.GetString("Countries_" + Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToUpper());
if (string.IsNullOrWhiteSpace(countriesJson))
countriesJson = _memoryCache.GetString("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 Country GetCountry(string countryCode)
{
var country = GetCountries().FirstOrDefault(c => String.Equals(c.Iso2, countryCode, StringComparison.CurrentCultureIgnoreCase));
return country;
}
///
/// Gibt eine Liste von Bundesländern zurück
///
/// Liste von Bundesländern
public List GetStates()
{
var statesJson = _memoryCache.GetString("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
Init();
statesJson = _memoryCache.GetString("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 List GetStates(string countryCode)
{
if (string.IsNullOrWhiteSpace(countryCode))
countryCode = "";
var statesJson = _memoryCache.GetString("States");
if (string.IsNullOrWhiteSpace(statesJson))
{
Init();
statesJson = _memoryCache.GetString("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 State GetState(string countryCode, string stateCode)
{
var states = GetStates(countryCode);
return states.FirstOrDefault(c => c.Code == stateCode);
}
///
/// Gibt eine Liste der Ländercodes zurück die zu einem Filter passen
///
/// Filter
/// Operator der angewendet werden soll
/// Liste gefundener Ländercodes
public List FindCountryCodes(string filter, string operatorValue)
{
var countries = GetCountries();
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 List FindStateCodes(string filter, string operatorValue)
{
var states = GetStates();
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();
}
}
///
/// Einstellungen für den Country-Service
///
public class CountryServiceOptions
{
///
/// ERstellt eine Instanz
///
public CountryServiceOptions()
{
}
///
/// Verfügbare Sprachen
///
public List Languages { get; set; }
///
/// Basis-Directory in welchem die Sprachdateien für die Länderauswahl zu finden sind
///
public string Directory { get; set; }
}
}