using Autofac;
using Coravel;
using Coravel.Events.Interfaces;
using InitQ;
using log4net;
using log4net.Config;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ropin.Core.Common;
using Ropin.Core.Extensions.ServiceExtensions;
using Ropin.Environmentally.WebScada.Hubs;
using Ropin.Environmentally.WebScada.Subscribe;
using Ropin.Inspection.Common.Helper;
using Ropin.Inspection.Model.Entities;
using Ropin.Inspection.Repository;
using Ropin.Inspection.Service;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Ropin.Environmentally.WebScada
{
    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            Env = env;
            var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
            XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config"));
        }
        //public Startup()//IConfiguration configuration
        //{
        //    //Configuration = configuration; 
        //    var configBuilder = new ConfigurationBuilder()
        //        .SetBasePath(Directory.GetCurrentDirectory())
        //        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
        //    Configuration = configBuilder.Build();
        //    var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
        //    XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config"));

        //}

        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Env { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        [Obsolete]
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(new Appsettings(Configuration));
            services.AddHttpClient();
            services.AddControllersWithViews();
            var rabbitMQ = Configuration.GetSection("RabbitMQ").Get<RabbitMQModel>();
            services.AddSingleton<RabbitMQModel>(rabbitMQ);
            var apiUrlData = Configuration.GetSection("APIUrl").Get<APIUrlData>();
            services.AddSingleton<APIUrlData>(apiUrlData);
            var IniInfluxData = Configuration.GetSection("IniInflux").Get<IniInfluxData>();
            services.AddSingleton<IniInfluxData>(IniInfluxData);
            //services.AddControllers();
            //services.AddScoped<IDbContextFactory, DbContextFactory>();
            //services.AddTransient<ITdevWebScadaDevSpotRepository, TdevWebScadaDevSpotRepository>();

            //services.AddRazorPages();
            //services.AddScoped<IPushMsgService, PushMsgService>();
            services.AddHostedService<Work.HostedService>();
            services.AddInitQ(m =>
            {
                m.SuspendTime = 1000;
                m.ConnectionString = Configuration["ConnectionSetting:RedisConnection"];
                m.ListSubscribe = new List<Type>() { typeof(RedisSubscribeBoxno), typeof(RedisIntervalSubscribeBoxno) };
                m.ShowLog = false;
            });
            services.AddNodeServices();
            services.AddSignalR();
            services.AddTransient<DevEventListener>();
            var connectionString = Configuration["ConnectionSetting:MySqlConnection"];
            ServerVersion serverVersion = ServerVersion.AutoDetect(connectionString);
            services.AddDbContext<InspectionDbContext>(options =>
                options.UseMySql(connectionString, serverVersion));
            //services.AddDbContextFactory<InspectionDbContext>(options =>
            //{
            //    options.UseMySql(connectionString, serverVersion)
            //        ;
            //});
            //���ܶೡ����Scoped�ֲ����������ǣ���ʱ�����Ҫע��һ��Singleton��DBContext�Ĺ�������
            services.AddSingleton<Func<InspectionDbContext>>(() =>
            {
                var optionsBuilder = new DbContextOptionsBuilder<InspectionDbContext>();
                optionsBuilder.UseMySql(connectionString, serverVersion);
            //��������������Ļ�������ͨ��provider.GetService<XX>()����ȡ
            return new InspectionDbContext(optionsBuilder.Options);
            });
            services.AddEvents();
            services.AddCors(options =>
            {
                options.AddPolicy("cors",
                    builder => builder
                    .SetIsOriginAllowed(_ => true)
                    .AllowAnyOrigin()
                    .AllowAnyHeader()
                    .AllowAnyMethod());
                options.AddDefaultPolicy(builder => {
                    builder.WithOrigins("https://example.com")
                    .AllowAnyHeader()
                    .WithMethods("GET", "POST")
                    .AllowCredentials();
                });
            });
        }
        public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterModule(new AutofacModuleRegister());
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                //app.UseSwagger();
                //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "UltrasonicAPI v1"));
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();
            app.UseCors("cors");
            var provider = app.ApplicationServices;
            IEventRegistration registration = provider.ConfigureEvents();
            registration.Register<DevEvent>().Subscribe<DevEventListener>();
            registration.Register<DevEvent>().Subscribe<DevRunEventListener>(); 
            //app.UseCors(option => option.WithOrigins("https://www.ropiniot.com").AllowCredentials().AllowAnyMethod().AllowAnyHeader());  //���ÿ���
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<MyHub>("myhub");
                endpoints.MapControllerRoute(
                   name: "default",
                   pattern: "{controller=Device}/{action=Index}/{id?}");
                //endpoints.MapRazorPages();
            });
        }
    }
}