using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegrator.Annotations.StateKeeping; using Telegrator.Filters.Components; using Telegrator.Handlers.Components; using Telegrator.MadiatorCore; using Telegrator.MadiatorCore.Descriptors; using Telegrator.StateKeeping.Abstracts; using Telegrator.StateKeeping.Components; namespace Telegrator.Handlers.Building.Components { /// /// Base class for building handler descriptors and managing handler filters. /// public abstract class HandlerBuilderBase(Type buildingHandlerType, UpdateType updateType, IHandlersCollection? handlerCollection) : IHandlerBuilder { private static int HandlerServiceKeyIndex = 0; /// /// to ehich new builded handlers is adding /// protected readonly IHandlersCollection? HandlerCollection = handlerCollection; /// /// of building handler /// protected readonly UpdateType UpdateType = updateType; /// /// Type of handler to build /// protected readonly Type BuildingHandlerType = buildingHandlerType; /// /// Filters applied to handler /// protected readonly List> Filters = []; /// /// of building handler /// protected DescriptorIndexer Indexer = new DescriptorIndexer(0, 0, 0); /// /// Update validation filter of building handler /// protected IFilter? ValidateFilter; /// /// State keeper of building handler /// protected IFilter? StateKeeper; /// /// Builds an implicit for the specified handler instance. /// /// The instance. /// The created . protected HandlerDescriptor BuildImplicitDescriptor(UpdateHandlerBase instance) { object handlerServiceKey = GetImplicitHandlerServiceKey(BuildingHandlerType); HandlerDescriptor descriptor = new HandlerDescriptor( DescriptorType.Implicit, BuildingHandlerType, UpdateType, Indexer, ValidateFilter, Filters.ToArray(), StateKeeper, handlerServiceKey, instance); HandlerCollection?.AddDescriptor(descriptor); return descriptor; } /// /// Gets a unique service key for an implicit handler type. /// /// The handler type. /// A unique service key string. public static object GetImplicitHandlerServiceKey(Type BuildingHandlerType) => string.Format("ImplicitHandler_{0}+{1}", HandlerServiceKeyIndex++, BuildingHandlerType.Name); /// /// Sets the update validating action for the handler. /// /// The to use. /// The builder instance. public void SetUpdateValidating(UpdateValidateAction validateAction) { ValidateFilter = new UpdateValidateFilter(validateAction); } /// /// Sets the concurrency level for the handler. /// /// The concurrency value. /// The builder instance. public void SetConcurreny(int concurrency) { Indexer = Indexer.UpdateImportance(concurrency); } /// /// Sets the priority for the handler. /// /// The priority value. /// The builder instance. public void SetPriority(int priority) { Indexer = Indexer.UpdatePriority(priority); } /// /// Sets both concurrency and priority for the handler. /// /// The concurrency value. /// The priority value. /// The builder instance. public void SetIndexer(int concurrency, int priority) { Indexer = new DescriptorIndexer(0, concurrency, priority); } /// /// Adds a filter to the handler. /// /// The to add. /// The builder instance. public void AddFilter(IFilter filter) { Filters.Add(filter); } /// /// Adds multiple filters to the handler. /// /// The filters to add. /// The builder instance. public void AddFilters(params IFilter[] filters) { Filters.AddRange(filters); } /// /// Sets a state keeper for the handler using a specific state and key resolver. /// /// The type of the key. /// The type of the state. /// The type of the state keeper. /// The state value. /// The key resolver. /// The builder instance. public void SetStateKeeper(TState myState, IStateKeyResolver keyResolver) where TKey : notnull where TState : IEquatable where TKeeper : StateKeeperBase, new() { StateKeeper = new StateKeepFilter(myState, keyResolver); } /// /// Sets a state keeper for the handler using a special state and key resolver. /// /// The type of the key. /// The type of the state. /// The type of the state keeper. /// The special state value. /// The key resolver. /// The builder instance. public void SetStateKeeper(SpecialState specialState, IStateKeyResolver keyResolver) where TKey : notnull where TState : IEquatable where TKeeper : StateKeeperBase, new() { StateKeeper = new StateKeepFilter(specialState, keyResolver); } /// /// Adds a targeted filter for a specific filter target type. /// /// The type of the filter target. /// Function to get the filter target from an update. /// The filter to add. /// The builder instance. public void AddTargetedFilter(Func getFilterringTarget, IFilter filter) where TFilterTarget : class { AnonymousTypeFilter anonymousTypeFilter = AnonymousTypeFilter.Compile(filter, getFilterringTarget); Filters.Add(anonymousTypeFilter); } /// /// Adds multiple targeted filters for a specific filter target type. /// /// The type of the filter target. /// Function to get the filter target from an update. /// The filters to add. /// The builder instance. public void AddTargetedFilters(Func getFilterringTarget, params IFilter[] filters) where TFilterTarget : class { AnonymousCompiledFilter compiledPollingFilter = AnonymousCompiledFilter.Compile(filters, getFilterringTarget); Filters.Add(compiledPollingFilter); } } }