using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;

namespace EasyDevCore.Configuration.Configuration
{
    /// <summary>
    /// 
    /// </summary>
    /// <seealso cref="Microsoft.Extensions.Configuration.IConfigurationSection" />
    public class EasyConfigurationSection : IConfigurationSection
    {
        private readonly IConfigurationSection _section;
        /// <summary>
        /// Initializes a new instance of the <see cref="EasyConfigurationSection"/> class.
        /// </summary>
        /// <param name="section">The section.</param>
        public EasyConfigurationSection(IConfigurationSection section)
        {
            _section = section;
        }

        /// <summary>
        /// Gets or sets the <see cref="System.String"/> with the specified key.
        /// </summary>
        /// <value>
        /// The <see cref="System.String"/>.
        /// </value>
        /// <param name="key">The key.</param>
        /// <returns></returns>
        public string this[string key]
        {
            get => _section[key] == null ? null : _section.GetConfigMapVariable<string>(key);
            set => _section[key] = value;
        }

        /// <summary>
        /// Gets the key this section occupies in its parent.
        /// </summary>
        public string Key => _section.Key;

        /// <summary>
        /// Gets the full path to this section within the <see cref="T:Microsoft.Extensions.Configuration.IConfiguration" />.
        /// </summary>
        public string Path => _section.Path;

        /// <summary>
        /// Gets or sets the section value.
        /// </summary>
        public string Value
        {
            get => _section.Value == null ? null : _section.ResolveConfigVariable<string>(_section.Value);
            set => _section.Value = value;
        }

        /// <summary>
        /// Gets a configuration sub-section with the specified key.
        /// </summary>
        /// <param name="key">The key of the configuration section.</param>
        /// <returns>
        /// The <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSection" />.
        /// </returns>
        /// <remarks>
        /// This method will never return <c>null</c>. If no matching sub-section is found with the specified key,
        /// an empty <see cref="T:Microsoft.Extensions.Configuration.IConfigurationSection" /> will be returned.
        /// </remarks>
        public IConfigurationSection GetSection(string key)
        {
            return new EasyConfigurationSection(_section.GetSection(key));
        }

        /// <summary>
        /// Gets the immediate descendant configuration sub-sections.
        /// </summary>
        /// <returns>
        /// The configuration sub-sections.
        /// </returns>
        public IEnumerable<IConfigurationSection> GetChildren()
        {
            return _section.GetChildren()
                .Select(x => new EasyConfigurationSection(x));
        }

        /// <summary>
        /// Returns a <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" /> that can be used to observe when this configuration is reloaded.
        /// </summary>
        /// <returns>
        /// A <see cref="T:Microsoft.Extensions.Primitives.IChangeToken" />.
        /// </returns>
        public IChangeToken GetReloadToken()
        {
            return _section.GetReloadToken();
        }
    }
}
