using CloudBuilder.Core.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

namespace CloudBuilder.Core.Application.Options
{
    /// <summary>
    /// CloudBuilder配置选项创建器
    /// </summary>
    public class CloudBuilderOptionsSetup : IConfigureOptions<CloudBuilderOptions>
    {
        private readonly IConfiguration _configuration;

        /// <summary>
        /// 初始化一个<see cref="CloudBuilderOptionsSetup"/>类型的新实例
        /// </summary>
        public CloudBuilderOptionsSetup(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        /// <summary>Invoked to configure a TOptions instance.</summary>
        /// <param name="options">The options instance to configure.</param>
        public void Configure(CloudBuilderOptions options)
        {
            SetDbContextOptions(options);

            IConfigurationSection section;

            //MailSender
            section = _configuration.GetSection("CloudBuilder:MailSender");
            MailSenderOptions sender = section.Get<MailSenderOptions>();
            if (sender != null)
            {
                if (sender.Password == null)
                {
                    sender.Password = _configuration["CloudBuilder:MailSender:Password"];
                }
                options.MailSender = sender;
            }

            //EnableGlobalAuthorize
            section = _configuration.GetSection("CloudBuilder:Authorization:EnableGlobalAuthorize");
            options.EnableGlobalAuthorize = section.Get<bool>();

            //JwtOptions
            section = _configuration.GetSection("CloudBuilder:Jwt");
            JwtOptions jwt = section.Get<JwtOptions>();
            if (jwt != null)
            {
                if (jwt.Secret == null)
                {
                    jwt.Secret = _configuration["CloudBuilder:Jwt:Secret"];
                }
                options.Jwt = jwt;
            }

            // RedisOptions
            section = _configuration.GetSection("CloudBuilder:Redis");
            RedisOptions redis = section.Get<RedisOptions>();
            if (redis != null)
            {
                if (redis.Configuration.IsMissing())
                {
                    throw new Exception("配置文件中Redis节点的Configuration不能为空");
                }
                options.Redis = redis;
            }

            //// SwaggerOptions
            //section = _configuration.GetSection("CloudBuilder:Swagger");
            //SwaggerOptions swagger = section.Get<SwaggerOptions>();
            //if (swagger != null)
            //{
            //    if (swagger.Url.IsMissing())
            //    {
            //        throw new CloudBuilderException("配置文件中Swagger节点的Url不能为空");
            //    }
            //    options.Swagger = swagger;
            //}

        }

        /// <summary>
        /// 初始化上下文配置信息，首先以CloudBuilder配置节点中的为准，
        /// 不存在CloudBuilder节点，才使用ConnectionStrings的数据连接串来构造SqlServer的配置，
        /// 保证同一上下文类型只有一个配置节点
        /// </summary>
        /// <param name="options"></param>
        private void SetDbContextOptions(CloudBuilderOptions options)
        {
            IConfigurationSection section = _configuration.GetSection("CloudBuilder:DbContexts");
            IDictionary<string, CloudBuilderDbContextOptions> dict = section.Get<Dictionary<string, CloudBuilderDbContextOptions>>();

            var repeated = dict.Values.GroupBy(m => m.DbContextTypeName).FirstOrDefault(m => m.Count() > 1);
            if (repeated != null)
            {
                throw new Exception($"数据上下文配置中存在多个配置节点指向同一个上下文类型：{repeated.First().DbContextTypeName}");
            }

            foreach (KeyValuePair<string, CloudBuilderDbContextOptions> pair in dict)
            {
                options.DbContexts.Add(pair.Key, pair.Value);
            }
        }
    }
}
