/*
* Copyright (c) 2023 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.Common.Enums;
using ProtonVPN.Client.Common.Extensions;
using ProtonVPN.Client.Logic.Connection.Contracts.Enums;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Features;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.Cities;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.Countries;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.FreeServers;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.Gateways;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.GatewayServers;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.Servers;
using ProtonVPN.Client.Logic.Connection.Contracts.Models.Intents.Locations.States;
namespace ProtonVPN.Client.Logic.Connection.Contracts.Extensions;
public static class IntentExtensions
{
public static string? GetCountryCode(this ILocationIntent locationIntent)
{
return locationIntent switch
{
SingleCountryLocationIntent countryIntent => countryIntent.CountryCode,
CityLocationIntentBase cityIntent => cityIntent.Country.CountryCode,
StateLocationIntentBase stateIntent => stateIntent.Country.CountryCode,
ServerLocationIntentBase serverIntent => serverIntent.Country.CountryCode,
SingleGatewayServerLocationIntent b2bServerIntent => b2bServerIntent.Server.CountryCode,
_ => string.Empty
};
}
public static FlagType GetFlagType(this ILocationIntent? locationIntent, bool isConnected = false)
{
return locationIntent switch
{
SingleCountryLocationIntent or
CityLocationIntentBase or
StateLocationIntentBase or
ServerLocationIntentBase => FlagType.Country,
SingleGatewayLocationIntent or
GatewayServerLocationIntentBase => FlagType.Gateway,
FreeServerLocationIntent freeServerIntent => freeServerIntent.Strategy switch
{
SelectionStrategy.Random when isConnected => FlagType.Country,
SelectionStrategy.Random => FlagType.Random,
_ => FlagType.Fastest,
},
IMultiLocationIntent multiLocationIntent => multiLocationIntent.Strategy switch
{
SelectionStrategy.Random => FlagType.Random,
_ => FlagType.Fastest,
},
_ => FlagType.Fastest,
};
}
public static FlagType GetFlagType(this IConnectionIntent? connectionIntent)
{
return GetFlagType(connectionIntent?.Location);
}
public static SelectionStrategy GetSelectionStrategy(this ILocationIntent locationIntent)
{
return locationIntent is IMultiLocationIntent multiLocationIntent
? multiLocationIntent.Strategy
: SelectionStrategy.Fastest;
}
public static IEnumerable GetIntentHierarchy(this ILocationIntent? locationIntent)
{
while (locationIntent != null)
{
yield return locationIntent;
locationIntent = locationIntent.GetBaseLocationIntent();
}
}
public static IEnumerable GetIntentHierarchy(this IFeatureIntent? featureIntent)
{
while (featureIntent != null)
{
yield return featureIntent;
featureIntent = featureIntent.GetBaseFeatureIntent();
}
}
public static ILocationIntent? GetBaseLocationIntent(this ILocationIntent locationIntent)
{
return locationIntent switch
{
// Server -> City -> (State) -> Single country -> Multi country
ServerLocationIntentBase serverIntent when serverIntent.City != null => serverIntent.City,
ServerLocationIntentBase serverIntent => serverIntent.Country,
CityLocationIntentBase cityIntent when cityIntent.State != null => cityIntent.State,
CityLocationIntentBase cityIntent => cityIntent.Country,
StateLocationIntentBase stateIntent => stateIntent.Country,
SingleCountryLocationIntent => MultiCountryLocationIntent.Default,
// Multi country with selection -> Multi country (all available)
MultiCountryLocationIntent countryIntent when !countryIntent.IsSelectionEmpty => countryIntent.Strategy switch
{
SelectionStrategy.Fastest => MultiCountryLocationIntent.Fastest,
SelectionStrategy.Random => MultiCountryLocationIntent.Random,
_ => MultiCountryLocationIntent.Default,
},
// Multi country -> Multi country excluding my country
MultiCountryLocationIntent countryIntent when !countryIntent.IsToExcludeMyCountry => countryIntent.Strategy switch
{
SelectionStrategy.Fastest => MultiCountryLocationIntent.FastestExcludingMyCountry,
SelectionStrategy.Random => MultiCountryLocationIntent.RandomExcludingMyCountry,
_ => MultiCountryLocationIntent.Default,
},
// Fastest country -> Random country
MultiCountryLocationIntent countryIntent when countryIntent.Strategy == SelectionStrategy.Fastest => MultiCountryLocationIntent.Random,
// Gateway server -> Single gateway -> Multi gateway (all available)
GatewayServerLocationIntentBase gatewayServerIntent => gatewayServerIntent.Gateway,
SingleGatewayLocationIntent => MultiGatewayLocationIntent.Default,
// Multi gateway with selection -> Multi gateway (all available)
MultiGatewayLocationIntent gatewayIntent when !gatewayIntent.IsSelectionEmpty => gatewayIntent.Strategy switch
{
SelectionStrategy.Fastest => MultiGatewayLocationIntent.Fastest,
SelectionStrategy.Random => MultiGatewayLocationIntent.Random,
_ => MultiGatewayLocationIntent.Default,
},
// Fastest gateway -> Random gateway
MultiGatewayLocationIntent gatewayIntent when gatewayIntent.Strategy == SelectionStrategy.Fastest => MultiGatewayLocationIntent.Random,
// Free server with exclusion -> Free server
FreeServerLocationIntent freeServerIntent when freeServerIntent.ServerToExclude != null => FreeServerLocationIntent.Default,
_ => null,
};
}
public static IFeatureIntent? GetBaseFeatureIntent(this IFeatureIntent featureIntent)
{
return featureIntent switch
{
// Secure core with entry country -> Secure core
SecureCoreFeatureIntent secureCoreIntent when !secureCoreIntent.IsFastest => SecureCoreFeatureIntent.Default,
_ => null,
};
}
}