using EasyDevCore.Common;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyDevCore.Configuration.Configuration
{

    /// <summary>
    /// 
    /// </summary>
    public static class EasyConfigurationExtensions
    {
        /// <summary>
        /// Resolves the macro value (like pattern {Property}) from config file.
        /// </summary>
        /// <param name="config">The configuration.</param>
        /// <param name="configSecrets">The configuration secrets.</param>
        /// <param name="sectionName">Name of the section.</param>
        /// <param name="resolveChildren">if set to <c>true</c> [resolve children].</param>
        /// <returns></returns>
        public static IConfiguration ResolveConfigSecrets(this IConfiguration config, EasyConfiguration configSecrets, string sectionName = "", bool resolveChildren = true)
        {
            var section = config;
            if (!string.IsNullOrWhiteSpace(sectionName))
            {
                section = config.GetSection(sectionName);
            }
            var list = resolveChildren ? section.GetAllChildren() : section.GetChildren();
            foreach(var item in list)
            {
                var value = item.Value;
                var found = BindSecretItem(configSecrets, ref value);
                if (found)
                {
                    item.Value = value;
                }
            }
            return config;
        }

        /// <summary>
        /// Binds the secret item.
        /// </summary>
        /// <param name="configSecrets">The configuration secrets.</param>
        /// <param name="configString">The configuration string.</param>
        /// <returns></returns>
        private static bool BindSecretItem(EasyConfiguration configSecrets, ref string configString)
        {
            var decodedValue = configString;
            var found = false;
            if (configString == null) return false;
            configString.RegexGroupMatch("{(?<m>[^{}]+)}", (m) =>
            {
                if (m.Value == "m" && configSecrets.Exists(m.Value))
                {
                    found = true;
                    decodedValue = decodedValue.Replace("{{" + m.Value + "}}", (configSecrets[m.Value] ?? "?Null?").ToString(), StringComparison.InvariantCultureIgnoreCase);
                }
            });
            if (found)
            {
                configString = decodedValue;
            }
            return found;
        }

        /// <summary>
        /// Resolves the secret item.
        /// </summary>
        /// <param name="configSecrets">The configuration secrets.</param>
        /// <param name="configString">The configuration string.</param>
        /// <returns></returns>
        public static string ResolveSecretItem(this EasyConfiguration configSecrets, string configString)
        {
            BindSecretItem(configSecrets, ref configString);
            return configString;
        }

    }
}
