private void SimulateAssetValueChanges()
        {
            var notificationSubscriptions = SubscriptionsManager.Subscriptions;

            var assets = _exchangeRatesProvider.GetAssets().GetAwaiter().GetResult().ToArray();
            var rnd    = new Random();
            var changedAssetsAmount = rnd.Next(assets.Length);

            for (var i = 0; i < changedAssetsAmount; i++)
            {
                var randomAssetInd = rnd.Next(assets.Length);
                var randomAsset    = assets[randomAssetInd];
                var assetValue     = _exchangeRatesProvider.GetAssetValue(randomAsset).GetAwaiter().GetResult();

                var matchedConditions = notificationSubscriptions.Where(ns =>
                                                                        ns.Predicate(assetValue) &&
                                                                        ns.Asset.Equals(randomAsset, StringComparison.InvariantCultureIgnoreCase))
                                        .ToArray();

                foreach (var matchedCondition in matchedConditions)
                {
                    AssetValueChangedEvent?.Invoke(this, new AssetValueChangedEventArgs
                    {
                        Asset  = matchedCondition.Asset,
                        ChatId = matchedCondition.ChatId,
                        Value  = assetValue
                    });
                }

                foreach (var cond in matchedConditions)
                {
                    _subscriptionsManager.Unsubscribe(cond.Asset, cond.ChatId, cond.Predicate);
                }
            }
        }
        public async Task <QuoteValueCriterionSubscriptionResponse> Process()
        {
            decimal currentValue;

            try
            {
                currentValue = await _exchangeRatesProvider.GetAssetValue(_asset);

                var conditionAlreadyApplies = _request.Predicate(currentValue);

                if (conditionAlreadyApplies)
                {
                    return(new QuoteValueCriterionSubscriptionResponse
                    {
                        Success = false,
                        ResultMessage = string.Format(MessageTexts.ConditionAlreadySatisfied, currentValue)
                    });
                }

                var alreadySubscribed = await _subscriptionsManager.AlreadySubscribed(_asset, _request.ChatId, _request.Predicate);

                if (alreadySubscribed)
                {
                    return(new QuoteValueCriterionSubscriptionResponse
                    {
                        Success = true,
                        ResultMessage = MessageTexts.AlreadySubscribed
                    });
                }
            }
            catch (Exception)
            {
                return(new QuoteValueCriterionSubscriptionResponse
                {
                    Success = false,
                    ResultMessage = MessageTexts.ConditionCheckFailed
                });
            }

            try
            {
                await _subscriptionsManager.Subscribe(_asset, _request.ChatId, _request.Predicate);

                return(new QuoteValueCriterionSubscriptionResponse
                {
                    Success = true,
                    ResultMessage = string.Format(MessageTexts.SubscribedSuccessfully, currentValue),
                    CurrentPrice = currentValue
                });
            }
            catch (Exception e)
            {
                return(new QuoteValueCriterionSubscriptionResponse
                {
                    Success = false,
                    ResultMessage = $"{MessageTexts.SubscriptionFailed}. {e.Message}"
                });
            }
        }