using System.IO;
using Interfaces;
using Nancy;
using Nancy.Authentication.Forms;
using Nancy.Bootstrapper;
using Nancy.Bootstrappers.Ninject;
using Nancy.Conventions;
using Nancy.Diagnostics;
using Ninject;
using RaceLapTimer.Extensions;
using RaceLapTimer.Extensions.FileExport;
using RaceLapTimer.Extensions.Notifications;
using RaceLapTimer.Extensions.SystemControl;
using RaceLapTimer.Extensions.TransponderUtilities;

namespace RaceLapTimer
{
    public class FormsAuthBootstrapper : NinjectNancyBootstrapper
    {
        protected override void ApplicationStartup(IKernel container, IPipelines pipelines)
        {
            base.ApplicationStartup(container, pipelines);
            Nancy.Security.Csrf.Enable(pipelines);
        }

        protected override void ConfigureApplicationContainer(IKernel container)
        {
            // We don't call "base" here to prevent auto-discovery of
            // types/dependencies
            // Configure things for a wider purpose, non-requestcontroller based.
            container.Bind<IContainerHelper>().To<ContainerHelper>();
            container.Bind<IPluginPathProvider>().To<PluginPathProvider>();
            container.Bind<IConfigFilePathProvider>().To<ConfigFilePathProvider>();
            container.Bind<IDocumentPathProvider>().To<DocumentPathProvider>();
            container.Bind<IPluginLocator>().To<PluginLocator>();
            container.Bind<IDbProvider>().To<TestProvider>().InSingletonScope();
            //load dynamic plugins..:
            var cfgFilePath = Path.Combine(container.Get<IConfigFilePathProvider>().GetPath, "NinjectConfig.xml");

            container.Load(cfgFilePath);

            container.Bind<INotifierManager>().To<NotificationManager>().InSingletonScope();
            container.Bind<ISystemControlManager>().To<SystemControlManager>().InSingletonScope();
            container.Bind<ITransponderUtilityManager>().To<TransponderUtilityManager>().InSingletonScope();

            //unused code, trying to get a friggin html to pdf converter working well. :(
            container.Bind<IExportManager>().To<FileExportManager>().InSingletonScope();

            //var testHtml = "<html><body><img src=\"http://knockoutjs.com/img/ko-logo.png\" alt=\"Syncfusion_logo\" width=\"200\" height=\"70\"><p>Hello World</p></body></html>";
            //var tu = container.Get<IExportManager>();
            //var id = tu.Export(testHtml, "http://localhost:8800");
            //File.Delete("testpdf.pdf");
            //using (FileStream fs = new FileStream("testpdf.pdf", FileMode.CreateNew))
            //{
            //    id.Seek(0, SeekOrigin.Begin);
            //    id.CopyTo(fs);
            //    id.Close();
            //    id.Dispose();
            //    fs.Flush(true);
            //    fs.Close(); //this still isnt saving the file.. :(
            //}
        }
        
        protected override void ConfigureRequestContainer(IKernel container, NancyContext context)
        {
            base.ConfigureRequestContainer(container, context);

            // Here we register our user mapper as a per-request singleton.
            // As this is now per-request we could inject a request scoped
            // database "context" or other request scoped services.
            container.Bind<IUserStorage>().To<UserStorage>();    //register the storage provider..
            container.Bind<IUserMapper>().To<UserDatabase>().InSingletonScope();
        }

        protected override void RequestStartup(IKernel requestContainer, IPipelines pipelines, NancyContext context)
        {
            // At request startup we modify the request pipelines to
            // include forms authentication - passing in our now request
            // scoped user name mapper.
            //
            // The pipelines passed in here are specific to this request,
            // so we can add/remove/update items in them as we please.
            var formsAuthConfiguration =
                new FormsAuthenticationConfiguration()
                {
                    RedirectUrl = "~/login",
                    UserMapper = requestContainer.Get<IUserMapper>(),
                };

            FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
        }

        protected override DiagnosticsConfiguration DiagnosticsConfiguration
        {
            get
            {
                return new DiagnosticsConfiguration { Password = "password" };
            }
        }

        protected override IRootPathProvider RootPathProvider { get { return new NancyRootPathProvider(); } }

        protected override void ConfigureConventions(NancyConventions conventions)
        {
            base.ConfigureConventions(conventions);
            conventions.StaticContentsConventions.Add(
                StaticContentConventionBuilder.AddDirectory("images", "images")
            );
            conventions.StaticContentsConventions.Add(
                StaticContentConventionBuilder.AddDirectory("js", "js")
            );
            conventions.StaticContentsConventions.Add(
                StaticContentConventionBuilder.AddDirectory("css", "css")
            );
            conventions.StaticContentsConventions.Add(
                StaticContentConventionBuilder.AddDirectory("fonts", "fonts")
            );
        }
    }
}
