/*
* Copyright (c) 2025 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see .
*/
using ProtonVPN.Client.Logic.Servers.Cache;
using ProtonVPN.Client.Logic.Servers.Contracts;
using ProtonVPN.Client.Logic.Servers.Contracts.Enums;
using ProtonVPN.Client.Logic.Servers.Contracts.Extensions;
using ProtonVPN.Client.Logic.Servers.Contracts.Models;
namespace ProtonVPN.Client.Logic.Servers;
public class ServersLoader : IServersLoader
{
private readonly IServersCache _serversCache;
private readonly IServerCountCache _serverCountCache;
public ServersLoader(
IServersCache serversCache,
IServerCountCache serverCountCache)
{
_serversCache = serversCache;
_serverCountCache = serverCountCache;
}
public int GetServerCount()
{
return _serverCountCache.GetServerCount();
}
public int GetCountryCount()
{
return _serverCountCache.GetCountryCount();
}
public Server? GetById(string serverId)
{
return GetServers().FirstOrDefault(s => s.Id == serverId);
}
public IEnumerable GetFreeCountries()
{
return _serversCache.FreeCountries;
}
public IEnumerable GetCountries()
{
return _serversCache.Countries;
}
public IEnumerable GetCountriesByFeatures(ServerFeatures serverFeatures)
{
return _serversCache.Countries.Where(c => c.Features.IsSupported(serverFeatures));
}
public bool HasAnyCountries()
{
return _serversCache.Countries.Any();
}
public IEnumerable GetStates()
{
return _serversCache.States;
}
public IEnumerable GetStatesByCountryCode(string countryCode)
{
return _serversCache.States.Where(s => s.CountryCode == countryCode);
}
public IEnumerable GetStatesByFeatures(ServerFeatures serverFeatures)
{
return _serversCache.States.Where(s => s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetStatesByFeaturesAndCountryCode(ServerFeatures serverFeatures, string countryCode)
{
return _serversCache.States.Where(s => s.CountryCode == countryCode
&& s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetCities()
{
return _serversCache.Cities;
}
public IEnumerable GetCitiesByCountryCode(string countryCode)
{
return _serversCache.Cities.Where(c => c.CountryCode == countryCode);
}
public IEnumerable GetCitiesByState(State state)
{
return _serversCache.Cities.Where(c => c.CountryCode == state.CountryCode
&& c.StateName == state.Name);
}
public IEnumerable GetCitiesByFeatures(ServerFeatures serverFeatures)
{
return _serversCache.Cities.Where(c => c.Features.IsSupported(serverFeatures));
}
public IEnumerable GetCitiesByFeaturesAndCountryCode(ServerFeatures serverFeatures, string countryCode)
{
return _serversCache.Cities.Where(c => c.CountryCode == countryCode
&& c.Features.IsSupported(serverFeatures));
}
public IEnumerable GetCitiesByFeaturesAndState(ServerFeatures serverFeatures, State state)
{
return _serversCache.Cities.Where(c => c.CountryCode == state.CountryCode
&& c.StateName == state.Name
&& c.Features.IsSupported(serverFeatures));
}
public IEnumerable GetServers()
{
return _serversCache.Servers;
}
private IEnumerable GetPaidServersByFilter(Func? filterFunc)
{
return GetServers()
.Where(s => s.Tier is ServerTiers.Basic or ServerTiers.Plus
&& (filterFunc is null || filterFunc(s))
&& !s.Features.IsB2B());
}
private IEnumerable GetFreeServersByFilter(Func? filterFunc)
{
return GetServers()
.Where(s => s.Tier == ServerTiers.Free
&& (filterFunc is null || filterFunc(s))
&& !s.Features.IsB2B());
}
private IEnumerable GetGatewayServersByFilter(Func? filterFunc)
{
return GetServers()
.Where(s => (filterFunc is null || filterFunc(s))
&& s.Features.IsB2B());
}
public IEnumerable GetFreeServers()
{
return GetFreeServersByFilter(null);
}
public IEnumerable GetFreeServersByFeatures(ServerFeatures serverFeatures)
{
return GetFreeServersByFilter(s => s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetServersByState(State state)
{
return GetPaidServersByFilter(s => s.ExitCountry == state.CountryCode
&& s.State == state.Name
&& s.IsStandard());
}
public IEnumerable GetServersByCity(City city)
{
return GetPaidServersByFilter(s => s.ExitCountry == city.CountryCode
&& s.State == city.StateName
&& s.City == city.Name
&& s.IsStandard());
}
public IEnumerable GetServersByFeatures(ServerFeatures serverFeatures)
{
return GetPaidServersByFilter(s => s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetServersByFeaturesAndCountryCode(ServerFeatures serverFeatures, string countryCode)
{
return GetPaidServersByFilter(s => s.ExitCountry == countryCode
&& s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetServersByFeaturesAndState(ServerFeatures serverFeatures, State state)
{
return GetPaidServersByFilter(s => s.ExitCountry == state.CountryCode
&& s.State == state.Name
&& s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetServersByFeaturesAndCity(ServerFeatures serverFeatures, City city)
{
return GetPaidServersByFilter(s => s.ExitCountry == city.CountryCode
&& s.State == city.StateName
&& s.City == city.Name
&& s.Features.IsSupported(serverFeatures));
}
public IEnumerable GetSecureCoreCountryPairs()
{
return _serversCache.SecureCoreCountryPairs;
}
public IEnumerable GetSecureCoreCountryPairsByExitCountryCode(string exitCountryCode)
{
return GetSecureCoreCountryPairs()
.Where(sccp => sccp.ExitCountry == exitCountryCode);
}
public IEnumerable GetServersBySecureCoreCountryPair(SecureCoreCountryPair countryPair)
{
return GetPaidServersByFilter(s => s.ExitCountry == countryPair.ExitCountry
&& s.EntryCountry == countryPair.EntryCountry
&& s.Features.IsSupported(ServerFeatures.SecureCore));
}
public IEnumerable GetGateways()
{
return _serversCache.Gateways;
}
public IEnumerable GetServersByGatewayName(string gatewayName)
{
return GetGatewayServersByFilter(s => s.GatewayName == gatewayName);
}
public bool HasAnyGateways()
{
return _serversCache.Gateways.Any();
}
}