using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authorization;
using Api.SignToken;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using System.IdentityModel.Tokens.Jwt;
using Pivotal.Discovery.Client;
using NLog.Extensions.Logging;
using NLog.Web;
using Microsoft.AspNetCore.Mvc.Versioning;
using MadRunFabric.Common.Options;
using AutoMapper;
using TestUserTypeApi.IRepositories;
using TestUserTypeApi.Repositories;
using MadRunFabric.Common;
using MadRunFabric.Common.DbContext;

namespace TestUserTypeApi
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            //Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Configuration = new ConfigurationBuilder()
                            .SetBasePath(env.ContentRootPath)
                            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                            .AddEnvironmentVariables()
                            .Build();
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Cors 配置
            //生产环境 的cors
            services.AddCors(options =>
            {
                options.AddPolicy("CorsProd",
                builder => builder.AllowAnyOrigin()
                //builder => builder.WithOrigins(Configuration["Cors"].Split(','))
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials().SetPreflightMaxAge(TimeSpan.FromMinutes(30)));
            });
            //开发环境的cors
            services.AddCors(options =>
            {
                options.AddPolicy("CorsDev",
                builder => builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials().SetPreflightMaxAge(TimeSpan.FromMinutes(30)));
            });
            #endregion

            //services.AddMvc();

            #region 授权配置
            ////读取jwt配置文件
            //var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"].ToString()));
            //var tokenValidationParameters = new TokenValidationParameters
            //{
            //    ValidateIssuerSigningKey = true,
            //    IssuerSigningKey = signingKey,
            //    ValidateIssuer = true,
            //    ValidIssuer = Configuration["Jwt:Issuer"].ToString(),//发行人
            //    ValidateAudience = true,
            //    ValidAudience = Configuration["Jwt:Audience"].ToString(),//订阅人
            //    ValidateLifetime = true,
            //    ClockSkew = TimeSpan.Zero,
            //    RequireExpirationTime = true,
            //};

            //services.AddAuthentication(options =>
            //{
            //    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            //    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            //})
            //.AddJwtBearer(o =>
            //{
            //    o.RequireHttpsMetadata = false;
            //    o.TokenValidationParameters = tokenValidationParameters;
            //    o.Events = new JwtBearerEvents
            //    {
            //        OnTokenValidated = context =>
            //        {
            //            if (context.Request.Path.Value.ToString() == "/api/logout")
            //            {
            //                var token = ((context as TokenValidatedContext).SecurityToken as JwtSecurityToken).RawData;
            //            }
            //            return Task.CompletedTask;
            //        }
            //    };
            //});
            #endregion

            #region configuration
            services.AddSingleton<IConfiguration>(Configuration);
            #endregion

            #region steeltoe
            services.AddDiscoveryClient(Configuration);
            #endregion

            #region redis配置
            services.AddDistributedRedisCache(options =>
            {
                options.InstanceName = Configuration["Redis:InstanceName"].ToString();
                options.Configuration = $"{Configuration["Redis:HostName"].ToString()}:{Configuration["Redis:Port"].ToString()},allowAdmin=true,password={Configuration["Redis:Password"].ToString()},defaultdatabase={Configuration["Redis:Defaultdatabase"].ToString()}";
            });
            #endregion

            services.AddSingleton<IConfiguration>(Configuration);

            //注入授权Handler
            services.AddSingleton<IAuthorizationHandler, PermissionAuthorizationHandler>();

            services.AddSingleton<IPermissionService, PermissionService>();
            services.AddSingleton<ISignTokenService, SignTokenService>();

            #region 版本控制
            services.AddApiVersioning(Options =>
            {
                Options.ReportApiVersions = true;//可选，为true API返回响应标头中支持的版本信息
                Options.ApiVersionReader = new QueryStringApiVersionReader(parameterName: "api-version");
                Options.AssumeDefaultVersionWhenUnspecified = true;
                Options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(6, 0);
            });
            #endregion


            #region AutoMapper
            services.AddAutoMapper();
            #endregion

            services.AddMvc(options =>
            {
                options.Filters.Add(new ActionFilter());
                options.Filters.Add(new ExceptionFilter());
            }).AddJsonOptions(op => op.SerializerSettings.ContractResolver =
                                        new Newtonsoft.Json.Serialization.DefaultContractResolver());

            #region Mongodb配置
            services.Configure<MongodbOptions>(options =>
            {
                options.ConnectionString = Configuration.GetSection("MongoConnection:ConnectionString").Value;
                options.Database = Configuration.GetSection("MongoConnection:Database").Value;
            });

            BaseOracleContext.DB_ConnectionString = Configuration.GetConnectionString("OracleConnection");
            #endregion

            #region steeltoe
            services.AddDiscoveryClient(Configuration);
            #endregion

            #region 添加仓储访问服务
            services.AddTransient<ItestusertypeRepository, TestusertypeRepository>();
            services.AddTransient<ItesttypeRepository, TesttypeRepository>();
            services.AddTransient<IUserDoTestRepository, UserDoTestRepository>();
            services.AddTransient<IUserTestRepository, UserTestRepository>();
            services.AddTransient<IMassageInfoRepository, MassageInfoRepository>();
            services.AddTransient<ItestquestionRepository, testquestionRepository>();
            services.AddTransient<IMassageTypeRepository, MassageTypeRepository>();
            services.AddTransient<ImsgonlinemapRepository, msgonlinemapRepository>();//聊天记录是否已读关联表
            services.AddTransient<ImsgonlineRepository, msgonlineRepository>();//聊天记录表
            services.AddTransient<IdiagnosisinfoRepository, diagnosisinfoRepository>();//会诊
            services.AddTransient<IpatientRepository, patientRepository>();//患者
            services.AddTransient<IdiagnosisinbasesRepository, diagnosisinbasesRepository>();//会诊人员信息

            services.AddTransient<IequipmentmanagementsRepository, equipmentmanagementsRepository>();//设备调配设备表
            services.AddTransient<IequipmentmanagementlistRepository, equipmentmanagementlistRepository>();//设备调配记录表

            services.AddTransient<ISzzysRepository, SzzysRepository>();//上转住院
            services.AddTransient<IHzjbxxRepository, HzjbxxRepository>();//患者信息
            services.AddTransient<ISzmzsRepository, SzmzsRepository>();//上转门诊
            services.AddTransient<ISzjcsRepository, SzjcsRepository>(); //上转检查
            services.AddTransient<IXzzlsRepository, XzzlsRepository>(); //下转治疗
            services.AddTransient<IXzzysRepository, XzzysRepository>();//下转住院
            services.AddTransient<IWjzqjsRepository, WjzqjsRepository>();//急危重抢救
            services.AddTransient<IBbsqsRepository, BbsqsRepository>();//标本收取
            services.AddTransient<IHzapsRepository, HzapsRepository>();//会诊安排
            services.AddTransient<IGzlrbsRepository, GzlrbsRepository>();//工作量日报
            services.AddTransient<IYyzlsRepository, YyzlsRepository>();//预约诊疗
            services.AddTransient<IFxdjtabsRepository, FxdjtabsRepository>();//风险等级
            services.AddTransient<IFxqytabsRepository, FxqytabsRepository>();//风险区域
            services.AddTransient<IYhpctabsRepository, YhpctabsRepository>();//隐患排查

            services.AddTransient<IdxsfjlsRepository, dxsfjlsRepository>();//患者出院信息
            services.AddTransient<ISys_User_AccountRepository, Sys_User_AccountRepository>();
            services.AddTransient<ITSys_AreaRepository, TSys_AreaRepository>();//测试调用oracle

            services.AddTransient<Iv_csm_zhuyuanRepository, v_csm_zhuyuanRepository>();//出院患者信息
            services.AddTransient<IGhcodesRepository, GhcodesRepository>();//工号表

            services.AddTransient<IHzsfMassagesRepository, HzsfMassagesRepository>();//住院患者发送短信记录表

            #endregion
            //services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsProduction())
            {
                app.UseCors("CorsProd");
            }
            else
            {
                app.UseCors("CorsDev");
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
                app.UseBrowserLink();
            }

            app.UseAuthentication();

            app.UseMvc();

            #region steeltoe
            app.UseDiscoveryClient();
            #endregion

            #region Nlog 引入
            loggerFactory.AddNLog();//添加NLog
            env.ConfigureNLog("nlog.config");//读取Nlog配置文件
            app.AddNLogWeb();
            #endregion
        }
    }
}
