/* * Copyright (c) 2026 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 System; using System.Collections.Generic; using ProtonVPN.Client.Logic.Connection.Contracts; using ProtonVPN.Client.Logic.Users.Contracts.Messages; using ProtonVPN.Client.Settings.Contracts; using ProtonVPN.StatisticalEvents.Contracts; using ProtonVPN.StatisticalEvents.Dimensions.Mappers; namespace ProtonVPN.StatisticalEvents.Dimensions.Builders; public class UpsellDimensionsBuilder : IUpsellDimensionsBuilder { private const string EXTERNAL_FLOW_TYPE = "external"; private readonly ISettings _settings; private readonly IConnectionManager _connectionManager; private readonly IModalSourceDimensionMapper _modalSourceDimensionMapper; private readonly IModalTriggerDimensionMapper _modalTriggerDimensionMapper; private readonly IVpnPlanTierDimensionMapper _vpnPlanTierDimensionMapper; private readonly IVpnPlanNameDimensionMapper _vpnPlanNameDimensionMapper; private readonly IDaysSinceAccountCreationDimensionMapper _daysSinceAccountCreationDimensionMapper; private readonly IOnOffDimensionMapper _onOffDimensionMapper; private readonly IYesNoDimensionMapper _yesNoDimensionMapper; private readonly IStringDimensionMapper _stringDimensionMapper; private readonly IPromoUrlDimensionMapper _promoUrlDimensionMapper; public UpsellDimensionsBuilder( ISettings settings, IConnectionManager connectionManager, IModalSourceDimensionMapper modalSourceDimensionMapper, IModalTriggerDimensionMapper modalTriggerDimensionMapper, IVpnPlanTierDimensionMapper vpnPlanTierDimensionMapper, IVpnPlanNameDimensionMapper vpnPlanNameDimensionMapper, IDaysSinceAccountCreationDimensionMapper daysSinceAccountCreationDimensionMapper, IOnOffDimensionMapper onOffDimensionMapper, IYesNoDimensionMapper yesNoDimensionMapper, IStringDimensionMapper stringDimensionMapper, IPromoUrlDimensionMapper promoUrlDimensionMapper) { _settings = settings; _connectionManager = connectionManager; _modalSourceDimensionMapper = modalSourceDimensionMapper; _modalTriggerDimensionMapper = modalTriggerDimensionMapper; _vpnPlanTierDimensionMapper = vpnPlanTierDimensionMapper; _vpnPlanNameDimensionMapper = vpnPlanNameDimensionMapper; _daysSinceAccountCreationDimensionMapper = daysSinceAccountCreationDimensionMapper; _onOffDimensionMapper = onOffDimensionMapper; _yesNoDimensionMapper = yesNoDimensionMapper; _stringDimensionMapper = stringDimensionMapper; _promoUrlDimensionMapper = promoUrlDimensionMapper; } public Dictionary Build(UpsellModalContext context, string? reference = null) { string? deviceCountryLocation = _settings.DeviceLocation?.CountryCode; DateTimeOffset? accountCreationDateUtc = _settings.UserCreationDateUtc; return new() { { "modal_source", _modalSourceDimensionMapper.Map(context.Source) }, { "modal_trigger", _modalTriggerDimensionMapper.Map(context.Trigger) }, { "vpn_status", _onOffDimensionMapper.Map(_connectionManager.IsConnected) }, { "user_country", _stringDimensionMapper.Map(deviceCountryLocation) }, { "new_free_plan_ui", _yesNoDimensionMapper.Map(true) }, { "days_since_account_creation", _daysSinceAccountCreationDimensionMapper.Map(accountCreationDateUtc) }, { "reference", _stringDimensionMapper.Map(reference) }, { "is_credential_less_enabled", _onOffDimensionMapper.Map(false) }, { "flow_type", EXTERNAL_FLOW_TYPE }, { "country", _stringDimensionMapper.Map(context.CountryCode) } }; } public Dictionary BuildAttemptDimensions() { return BuildAttemptOrDisplayDimensions(); } public Dictionary BuildDisplayDimensions() { return BuildAttemptOrDisplayDimensions(); } private Dictionary BuildAttemptOrDisplayDimensions() { VpnPlan vpnPlan = _settings.VpnPlan; return new() { { "user_plan", _vpnPlanNameDimensionMapper.Map(vpnPlan) }, { "user_tier", _vpnPlanTierDimensionMapper.Map(vpnPlan) }, }; } public Dictionary BuildSuccessDimensions(string url, VpnPlan oldPlan, VpnPlan newPlan) { Uri? promoUri = null; if (!string.IsNullOrWhiteSpace(url) && Uri.TryCreate(url, UriKind.Absolute, out Uri? absoluteUri)) { promoUri = absoluteUri; } return new() { { "user_plan", _vpnPlanNameDimensionMapper.Map(oldPlan) }, { "user_tier", _vpnPlanTierDimensionMapper.Map(oldPlan) }, { "upgraded_user_plan", _vpnPlanNameDimensionMapper.Map(newPlan) }, { "upgraded_user_tier", _vpnPlanTierDimensionMapper.Map(newPlan) }, { "billing_cycle", _promoUrlDimensionMapper.MapBillingCycle(promoUri) }, { "coupon_code", _promoUrlDimensionMapper.MapCouponCode(promoUri) }, }; } }