using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Diagnostics;
using Owin;
//
// Beispiele für den Aufruf von owinhost
// owinhost /v /p=8082 OwinSample.Startup
// owinhost /v /url=http://localhost:8082/owinhost OwinSample.Startup
//
using OwinSample.BasicAuthMiddleware;

namespace OwinSample
{

    using AppFunc = Func<IDictionary<string, object>, Task>;
    using AppFuncFactory = Func<Func<IDictionary<string, object>, Task>, Func<IDictionary<string, object>, Task>>;

    using Microsoft.Owin.Security;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.AspNet.Identity;


    public class HelloWorldMiddlewareOptions
    {
        public String Name { get; set; }

    }

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            //
            // Anmkerungen zur Preview (Stand Mitte August 2013): Fehlermeldungen die hier auftreten, werden nicht zwangsläufig weitergereicht (Ressourcen fehlen ...)
            //


            //SetUpWindowsAuth(app);


            //RegisterCustomMiddlewareUsingFactoryFunction(app);

            //RegisterHandlerFunction(app);

            //app.UseDiagnosticsPage();
            
            //app.UseDiagnosticsPage("/diagnostics");
            app.UseWelcomePage("/");
            //app.UseWelcomePage("/welcome");

            app.UseCookieAuthentication(new CookieAuthenticationOptions { 
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                AuthenticationMode = AuthenticationMode.Passive
            });

            app.UseHttpBasic(new HttpBasicAuthenticationOptions
            {
                AuthenticationMode = AuthenticationMode.Active,
                OnValidateCredentials = (user, pwd) => {
                    if (user == "max" && pwd == "geheim") return true;
                    return false;
                }
            });

            //RegisterErrorPageAndErrorHandler(app);

            //app.UseType<HelloWorldOwinMiddleware>("Katana");
            //app.UseHelloWorldMiddleware("Katana");

           
            //app.UseUglyHelloWorldMiddleware();
            //app.UseWelcomePage();

            // RegisterHttpBasicAuthMiddleware(app, AuthenticationMode.Passive);

            

            RegisterWebAPi(app);

            //RegisterSignalR(app);

            // app.MapConnection<...>()
        }

        private static void SetUpWindowsAuth(IAppBuilder app)
        {
            HttpListener listener = (HttpListener) app.Properties["System.Net.HttpListener"];
            listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
        }

        private static void RegisterHttpBasicAuthMiddleware(IAppBuilder app, AuthenticationMode mode)
        {
            var options = new HttpBasicAuthenticationOptions();
            options.AuthenticationMode = mode;

            options.OnValidateCredentials = (user, pwd) =>
            {
                if (user == "max" && pwd == "geheim") return true;
                return false;
            };
            app.UseType(typeof (HttpBasicAuthenticationMiddleware), options);
        }

        private void RegisterSignalR(IAppBuilder app)
        {
            var config = new HubConfiguration();
            //config.EnableCrossDomain = true;

            //app.MapHubs(config); // path kann auch gesetzt werden.
            app.MapSignalR(config);
        }

        private void RegisterWebAPi(IAppBuilder app)
        {
            var config = new HttpConfiguration();
            config.Routes.MapHttpRoute("Default", "api/{controller}/{id}", new {id = RouteParameter.Optional});
            app.UseWebApi(config);
        }

        private void RegisterErrorPageAndErrorHandler(IAppBuilder app)
        {
            app.UseErrorPage();
            app.UseHandlerAsync((req, res) => { throw new Exception("Sample-Exception ..."); });
            
        }

        private void RegisterSimpleHandlerFunction(IAppBuilder app)
        {
            app.UseHandlerAsync((req, res) =>
            {
                res.ContentType = "text/html";
                return res.WriteAsync("<b>Hallo Welt!</b>");
            });
        }

        private void RegisterHandlerFunction(IAppBuilder app)
        {
            app.UseHandlerAsync((req, res, next) =>
            {
                if (req.Path != "/hello")
                {
                    return next();
                }

                res.ContentType = "text/html";
                return res.WriteAsync("<b>Hallo Welt!</b>");
            });
        }

        private static void RegisterCustomMiddlewareUsingFactoryFunction(IAppBuilder app)
        {
            AppFuncFactory factoryFunc = CreateMiddlware;
            app.Use(factoryFunc);
        }

        private static AppFunc CreateMiddlware(AppFunc next)
        {
            AppFunc middlewareFunc = async (env) =>
            {
                var requestPath = (string) env["owin.RequestPath"];

                if (requestPath != "/hello")
                {
                    await next(env);
                    return;
                }

                var requestMethod = (string) env["owin.RequestMethod"];
                var responseBody = (Stream) env["owin.ResponseBody"];
                var responseHeaders = (IDictionary<string, string[]>) env["owin.ResponseHeaders"];

                using (var responseWriter = new StreamWriter(responseBody))
                {
                    Debug.WriteLine(requestMethod + " " + requestPath);

                    responseHeaders["Content-Type"] = new[] {"text/html"};

                    await responseWriter.WriteLineAsync("<b>" + "Hello World!" + "</b>");

                    // if (next != null) await next(env);
                }
            };
            return middlewareFunc;
        }
        }

}
