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);
}
}
}