using System;
using System.Collections.Generic;
using System.Text;

#if NETFX
using System.Web;
#endif

namespace Apewer.Web
{

    /// <summary></summary>
    public partial class ApiProgram
    {

        /// <summary>调用器。</summary>
        private static ApiInvoker _invoker = new ApiInvoker() { Logger = new Logger(), Options = new ApiOptions() };

        /// <summary>API 选项。</summary>
        public static ApiOptions Options { get => _invoker.Options; }

        /// <summary>日志记录器。</summary>
        public static Logger Logger { get => _invoker.Logger; }

        /// <summary>获取或设置 API 入口。</summary>
        public static ApiEntries Entries { get => _invoker.Entries; set => _invoker.Entries = value; }

        private Action _initializer = null;

        /// <summary></summary>
        public ApiProgram(Action initializer = null)
        {
            _initializer = initializer;
        }

    }

    // Listener
    public partial class ApiProgram
    {

        static HttpListener _listener = null;

        /// <summary>在后台启动 Listener,返回错误消息。</summary>
        /// <param name="ip">监听的本地 IP 地址。</param>
        /// <param name="port">监听的端口。</param>
        public static string Listener(string ip, int port = 80)
        {
            if (_listener == null) return "无法重复启动默认 Listener 实例。";

            var server = new HttpListener();
            server.IP = ip;
            server.Port = port;
            server.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
            var exception = server.Start();
            if (exception != null) return exception.Message;

            return null;
        }

        /// <summary>在后台启动 Listener,返回错误消息。</summary>
        /// <param name="ip">监听的本地 IP 地址。</param>
        /// <param name="port">监听的端口。</param>
        public static string Listener(int port = 80, string ip = "0.0.0.0")
        {
            if (_listener == null) return "无法重复启动默认 Listener 实例。";

            var server = new HttpListener();
            server.IP = ip;
            server.Port = port;
            server.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
            var exception = server.Start();
            if (exception != null) return exception.Message;

            return null;
        }

    }

#if NETCORE

    // Kestrel & HTTP.Sys
    public partial class ApiProgram
    {

        static AspNetCoreServer _aspnetcore = null;

        class Startup : AspNetCoreStartup
        {

            public override void OnContext(Microsoft.AspNetCore.Http.HttpContext context)
            {
                if (_invoker == null) return;
                _invoker.Invoke(new AspNetCoreProvider(context));
            }

        }

        /// <summary>启动 Kestrel 服务器。</summary>
        public static void Kestrel(int port = 80)
        {
            if (_aspnetcore != null) return;
            var server = new KestrelServer();
            server.Port = port;
            server.Run<Startup>();
            _aspnetcore = server;
        }

        /// <summary>启动 HTTP.sys 服务器。</summary>
        public static void HttpSys(int port = 80, string ip = null)
        {
            if (_aspnetcore != null) return;
            var server = new HttpSysServer();
            server.Port = port;
            server.Run<Startup>();
            _aspnetcore = server;
        }

    }

#endif

#if NETFX

    // IIS
    public partial class ApiProgram : IHttpHandler, IHttpModule
    {

    #region IHttpHandler

        /// <summary></summary>
        public bool IsReusable { get { return false; } }

        /// <summary></summary>
        public void ProcessRequest(HttpContext context)
        {
            _initializer?.Invoke();
            _invoker.Invoke(new WebsiteProvider(context));
        }

    #endregion

    #region IHttpModule

        /// <summary></summary>
        public void Dispose() { }

        /// <summary></summary>
        public void Init(HttpApplication application)
        {
            application.PreSendRequestHeaders += (s, e) =>
            {
                // 从 Response 头中移除 Server 和 X-Powered-By 属性。
                var response = application.Response;
                var keys = new List<string>(response.Headers.AllKeys);
                if (keys.Contains("Server")) response.Headers.Remove("Server");
                if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By");
            };
        }

        IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData)
        {
            return null;
        }

        void EndEventHandler(IAsyncResult ar)
        {
        }

    #endregion

    }

#endif

}