using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Text;
using Telegram.Bot.Types.Enums;
using Telegrator.Configuration;
using Telegrator.Hosting.Components;
using Telegrator.MadiatorCore;
using Telegrator.MadiatorCore.Descriptors;
namespace Telegrator.Hosting
{
///
/// Represents a hosted telegram bot
///
public class TelegramBotHost : ITelegramBotHost
{
private readonly IHost _innerHost;
private readonly IServiceProvider _serviceProvider;
private readonly IUpdateRouter _updateRouter;
private readonly ILogger _logger;
private bool _disposed;
///
public IServiceProvider Services => _serviceProvider;
///
public IUpdateRouter UpdateRouter => _updateRouter;
///
/// This application's logger
///
public ILogger Logger => _logger;
///
/// Initializes a new instance of the class.
///
/// The proxied instance of host builder.
///
public TelegramBotHost(HostApplicationBuilder hostApplicationBuilder, IHandlersCollection handlers)
{
// Registering this host in services for easy access
RegisterHostServices(hostApplicationBuilder.Services, handlers);
// Building proxy hoster
_innerHost = hostApplicationBuilder.Build();
_serviceProvider = _innerHost.Services;
// Initializing bot info, as it requires to make a request via tg bot
Services.GetRequiredService();
// Reruesting services for this host
_updateRouter = Services.GetRequiredService();
_logger = Services.GetRequiredService>();
// Logging registering handlers in DEBUG purposes
LogHandlers(handlers);
}
///
/// Creates new with default configuration, services and long-polling update receiving scheme
///
///
public static TelegramBotHostBuilder CreateBuilder()
{
HostApplicationBuilder innerBuilder = new HostApplicationBuilder(settings: null);
TelegramBotHostBuilder builder = new TelegramBotHostBuilder(innerBuilder, null);
builder.Services.AddTelegramBotHostDefaults();
builder.Services.AddTelegramReceiver();
return builder;
}
///
/// Creates new with default services and long-polling update receiving scheme
///
///
public static TelegramBotHostBuilder CreateBuilder(TelegramBotHostBuilderSettings? settings)
{
HostApplicationBuilder innerBuilder = new HostApplicationBuilder(settings?.ToApplicationBuilderSettings());
TelegramBotHostBuilder builder = new TelegramBotHostBuilder(innerBuilder, settings);
builder.Services.AddTelegramBotHostDefaults();
builder.Services.AddTelegramReceiver();
return builder;
}
///
/// Creates new EMPTY WITHOUT any services or update receiving schemes
///
///
public static TelegramBotHostBuilder CreateEmptyBuilder()
{
HostApplicationBuilder innerBuilder = Host.CreateEmptyApplicationBuilder(null);
return new TelegramBotHostBuilder(innerBuilder, null);
}
///
/// Creates new EMPTY WITHOUT any services or update receiving schemes
///
///
public static TelegramBotHostBuilder CreateEmptyBuilder(TelegramBotHostBuilderSettings? settings)
{
HostApplicationBuilder innerBuilder = Host.CreateEmptyApplicationBuilder(null);
return new TelegramBotHostBuilder(innerBuilder, settings);
}
///
public async Task StartAsync(CancellationToken cancellationToken = default)
{
await _innerHost.StartAsync(cancellationToken);
}
///
public async Task StopAsync(CancellationToken cancellationToken = default)
{
await _innerHost.StopAsync(cancellationToken);
}
///
/// Disposes the host.
///
public void Dispose()
{
if (_disposed)
return;
_innerHost.Dispose();
GC.SuppressFinalize(this);
_disposed = true;
}
private void LogHandlers(IHandlersCollection handlers)
{
StringBuilder logBuilder = new StringBuilder("Registered handlers : ");
if (!handlers.Keys.Any())
throw new Exception();
foreach (UpdateType updateType in handlers.Keys)
{
HandlerDescriptorList descriptors = handlers[updateType];
logBuilder.Append("\n\tUpdateType." + updateType + " :");
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
{
logBuilder.AppendFormat("\n\t* {0} - {1}",
descriptor.Indexer.ToString(),
descriptor.ToString());
}
}
Logger.LogInformation(logBuilder.ToString());
}
private void RegisterHostServices(IServiceCollection services, IHandlersCollection handlers)
{
//services.RemoveAll();
//services.AddSingleton(this);
services.AddSingleton(this);
services.AddSingleton(this);
services.AddSingleton(handlers);
if (handlers is IHandlersManager manager)
{
services.RemoveAll();
services.AddSingleton(manager);
services.AddSingleton(manager);
}
}
}
}