using Amazon.Lambda.AspNetCoreServer.Internal;
using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
using Amazon.Lambda.Serialization.SystemTextJson;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
namespace Amazon.Lambda.AspNetCoreServer.Hosting.Internal
{
    /// 
    /// Subclass of Amazon.Lambda.AspNetCoreServer.LambdaServer that also starts
    /// up Amazon.Lambda.RuntimeSupport as part of the IServer startup.
    /// 
    /// This is an abstract class with subclasses for each of the possible Lambda event sources.
    /// 
    public abstract class LambdaRuntimeSupportServer : LambdaServer
    {
        IServiceProvider _serviceProvider;
        internal ILambdaSerializer Serializer;
        /// 
        /// Creates an instance on the LambdaRuntimeSupportServer
        /// 
        /// The IServiceProvider created for the ASP.NET Core application
        public LambdaRuntimeSupportServer(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            Serializer = serviceProvider.GetRequiredService();
        }
        /// 
        /// Start Amazon.Lambda.RuntimeSupport to listen for Lambda events to be processed.
        /// 
        /// 
        /// 
        /// 
        /// 
        public override Task StartAsync(IHttpApplication application, CancellationToken cancellationToken)
        {
            base.StartAsync(application, cancellationToken);
            var handlerWrapper = CreateHandlerWrapper(_serviceProvider);
            var bootStrap = new LambdaBootstrap(handlerWrapper);
            return bootStrap.RunAsync();
        }
        /// 
        /// Abstract method that creates the HandlerWrapper that will be invoked for each Lambda event.
        /// 
        /// 
        /// 
        protected abstract HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceProvider);
    }
    /// 
    /// IServer for handlying Lambda events from an API Gateway HTTP API.
    /// 
    public class APIGatewayHttpApiV2LambdaRuntimeSupportServer : LambdaRuntimeSupportServer
    {
        /// 
        /// Create instances
        /// 
        /// The IServiceProvider created for the ASP.NET Core application
        public APIGatewayHttpApiV2LambdaRuntimeSupportServer(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }
        /// 
        /// Creates HandlerWrapper for processing events from API Gateway HTTP API
        /// 
        /// 
        /// 
        protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceProvider)
        {
            var handler = new APIGatewayHttpApiV2MinimalApi(serviceProvider).FunctionHandlerAsync;
            return HandlerWrapper.GetHandlerWrapper(handler, this.Serializer);
        }
        /// 
        /// Create the APIGatewayHttpApiV2ProxyFunction passing in the ASP.NET Core application's IServiceProvider
        /// 
        public class APIGatewayHttpApiV2MinimalApi : APIGatewayHttpApiV2ProxyFunction
        {
            /// 
            /// Create instances
            /// 
            /// The IServiceProvider created for the ASP.NET Core application
            public APIGatewayHttpApiV2MinimalApi(IServiceProvider serviceProvider)
                : base(serviceProvider)
            {
            }
        }
    }
    /// 
    /// IServer for handlying Lambda events from an API Gateway REST API.
    /// 
    public class APIGatewayRestApiLambdaRuntimeSupportServer : LambdaRuntimeSupportServer
    {
        /// 
        /// Create instances
        /// 
        /// The IServiceProvider created for the ASP.NET Core application
        public APIGatewayRestApiLambdaRuntimeSupportServer(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }
        /// 
        /// Creates HandlerWrapper for processing events from API Gateway REST API
        /// 
        /// 
        /// 
        protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceProvider)
        {
            var handler = new APIGatewayRestApiMinimalApi(serviceProvider).FunctionHandlerAsync;
            return HandlerWrapper.GetHandlerWrapper(handler, this.Serializer);
        }
        /// 
        /// Create the APIGatewayProxyFunction passing in the ASP.NET Core application's IServiceProvider
        /// 
        public class APIGatewayRestApiMinimalApi : APIGatewayProxyFunction
        {
            /// 
            /// Create instances
            /// 
            /// The IServiceProvider created for the ASP.NET Core application
            public APIGatewayRestApiMinimalApi(IServiceProvider serviceProvider)
                : base(serviceProvider)
            {
            }
        }
    }
    /// 
    /// IServer for handlying Lambda events from an Application Load Balancer.
    /// 
    public class ApplicationLoadBalancerLambdaRuntimeSupportServer : LambdaRuntimeSupportServer
    {
        /// 
        /// Create instances
        /// 
        /// The IServiceProvider created for the ASP.NET Core application
        public ApplicationLoadBalancerLambdaRuntimeSupportServer(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
        }
        /// 
        /// Creates HandlerWrapper for processing events from API Gateway REST API
        /// 
        /// 
        /// 
        protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceProvider)
        {
            var handler = new ApplicationLoadBalancerMinimalApi(serviceProvider).FunctionHandlerAsync;
            return HandlerWrapper.GetHandlerWrapper(handler, this.Serializer);
        }
        /// 
        /// Create the ApplicationLoadBalancerFunction passing in the ASP.NET Core application's IServiceProvider
        /// 
        public class ApplicationLoadBalancerMinimalApi : ApplicationLoadBalancerFunction
        {
            /// 
            /// Create instances
            /// 
            /// The IServiceProvider created for the ASP.NET Core application
            public ApplicationLoadBalancerMinimalApi(IServiceProvider serviceProvider)
                : base(serviceProvider)
            {
            }
        }
    }
}