// <auto-generated/>

#nullable enable annotations
#nullable disable warnings

// Suppress warnings about [Obsolete] member usage in generated code.
#pragma warning disable CS0612, CS0618

namespace System.Runtime.CompilerServices
{
    using System;
    using System.CodeDom.Compiler;

    [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")]
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    file sealed class InterceptsLocationAttribute : Attribute
    {
        public InterceptsLocationAttribute(int version, string data)
        {
        }
    }
}

namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
    using Microsoft.Extensions.Configuration;
    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Runtime.CompilerServices;

    [GeneratedCode("Microsoft.Extensions.Configuration.Binder.SourceGeneration", "42.42.42.42")]
    file static class BindingExtensions
    {
        #region IConfiguration extensions.
        /// <summary>Attempts to bind the configuration instance to a new instance of type T.</summary>
        [InterceptsLocation(1, "R+J95cfVt+aeGOS40ZJnXPoBAABzcmMtMC5jcw==")] // src-0.cs(18,23)
        [InterceptsLocation(1, "R+J95cfVt+aeGOS40ZJnXFICAABzcmMtMC5jcw==")] // src-0.cs(21,23)
        [InterceptsLocation(1, "R+J95cfVt+aeGOS40ZJnXH0CAABzcmMtMC5jcw==")] // src-0.cs(22,15)
        public static T? Get<T>(this IConfiguration configuration, Action<BinderOptions>? configureOptions) => (T?)(GetCore(configuration, typeof(T), configureOptions) ?? default(T));

        /// <summary>Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively.</summary>
        [InterceptsLocation(1, "R+J95cfVt+aeGOS40ZJnXNsBAABzcmMtMC5jcw==")] // src-0.cs(17,23)
        public static void Bind_Options(this IConfiguration configuration, object? instance)
        {
            if (configuration is null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (instance is null)
            {
                return;
            }

            var typedObj = (global::Options)instance;
            BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null);
        }
        #endregion IConfiguration extensions.

        #region Core binding extensions.
        private readonly static Lazy<HashSet<string>> s_configKeys_RecordAction = new(() => new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "x" });
        private readonly static Lazy<HashSet<string>> s_configKeys_Options = new(() => new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Name", "Age", "List", "Array", "Record" });

        public static object? GetCore(this IConfiguration configuration, Type type, Action<BinderOptions>? configureOptions)
        {
            if (configuration is null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            BinderOptions? binderOptions = GetBinderOptions(configureOptions);

            if (!HasValueOrChildren(configuration))
            {
                return null;
            }

            if (type == typeof(global::Options))
            {
                var instance = new global::Options();
                BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions);
                return instance;
            }
            else if (type == typeof(global::System.Collections.Generic.List<global::System.IntPtr>))
            {
            }
            else if (type == typeof(global::MyDictionary))
            {
            }

            throw new NotSupportedException($"Unable to bind to type '{type}': generator did not detect the type as input.");
        }

        public static void BindCore(IConfiguration configuration, ref global::System.Collections.Generic.List<string> instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
        {
            foreach (IConfigurationSection section in configuration.GetChildren())
            {
                if (section.Value is string value)
                {
                    instance.Add(value);
                }
            }
        }

        public static void BindCore(IConfiguration configuration, ref string[] instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
        {
            var temp1 = new List<string>();

            foreach (IConfigurationSection section in configuration.GetChildren())
            {
                if (section.Value is string value)
                {
                    temp1.Add(value);
                }
            }

            int originalCount = instance.Length;
            Array.Resize(ref instance, originalCount + temp1.Count);
            temp1.CopyTo(instance, originalCount);
        }

        public static void BindCore(IConfiguration configuration, ref global::Record<global::System.Action> instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
        {
            ValidateConfigurationKeys(typeof(global::Record<global::System.Action>), s_configKeys_RecordAction, configuration, binderOptions);
        }

        public static void BindCore(IConfiguration configuration, ref global::Options instance, bool defaultValueIfNotFound, BinderOptions? binderOptions)
        {
            ValidateConfigurationKeys(typeof(global::Options), s_configKeys_Options, configuration, binderOptions);

            if (configuration["Name"] is string value2)
            {
                instance.Name = value2;
            }
            else if (defaultValueIfNotFound)
            {
                var currentValue = instance.Name;
                if (currentValue is not null)
                {
                    instance.Name = currentValue;
                }
            }

            if (configuration["Age"] is string value3 && !string.IsNullOrEmpty(value3))
            {
                instance.Age = ParseInt(value3, configuration.GetSection("Age").Path);
            }
            else if (defaultValueIfNotFound)
            {
                instance.Age = instance.Age;
            }

            if (AsConfigWithChildren(configuration.GetSection("List")) is IConfigurationSection section4)
            {
                global::System.Collections.Generic.List<string>? temp6 = instance.List;
                temp6 ??= new global::System.Collections.Generic.List<string>();
                BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions);
                instance.List = temp6;
            }
            else
            {
                instance.List = instance.List;
            }

            if (AsConfigWithChildren(configuration.GetSection("Array")) is IConfigurationSection section7)
            {
                string[]? temp9 = instance.Array;
                temp9 ??= new string[0];
                BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions);
                instance.Array = temp9;
            }
            else
            {
                instance.Array = instance.Array;
            }

            if (AsConfigWithChildren(configuration.GetSection("Record")) is IConfigurationSection section10)
            {
                global::Record<global::System.Action>? temp12 = instance.Record;
                temp12 ??= InitializeRecordAction(section10, binderOptions);
                BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions);
                instance.Record = temp12;
            }
            else
            {
                instance.Record = instance.Record;
            }
        }

        public static global::Record<global::System.Action> InitializeRecordAction(IConfiguration configuration, BinderOptions? binderOptions)
        {
            int x = (int)(10);
            if (configuration["x"] is string value13 && !string.IsNullOrEmpty(value13))
            {
                x = ParseInt(value13, configuration.GetSection("x").Path);
            }

            return new global::Record<global::System.Action>(x)
            {
                x = x,
            };
        }


        /// <summary>If required by the binder options, validates that there are no unknown keys in the input configuration object.</summary>
        public static void ValidateConfigurationKeys(Type type, Lazy<HashSet<string>> keys, IConfiguration configuration, BinderOptions? binderOptions)
        {
            if (binderOptions?.ErrorOnUnknownConfiguration is true)
            {
                List<string>? temp = null;
        
                foreach (IConfigurationSection section in configuration.GetChildren())
                {
                    if (!keys.Value.Contains(section.Key))
                    {
                        (temp ??= new List<string>()).Add($"'{section.Key}'");
                    }
                }
        
                if (temp is not null)
                {
                    throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
                }
            }
        }

        public static bool HasValueOrChildren(IConfiguration configuration)
        {
            if ((configuration as IConfigurationSection)?.Value is not null)
            {
                return true;
            }
            return AsConfigWithChildren(configuration) is not null;
        }

        public static IConfiguration? AsConfigWithChildren(IConfiguration configuration)
        {
            foreach (IConfigurationSection _ in configuration.GetChildren())
            {
                return configuration;
            }
            return null;
        }

        public static BinderOptions? GetBinderOptions(Action<BinderOptions>? configureOptions)
        {
            if (configureOptions is null)
            {
                return null;
            }
        
            BinderOptions binderOptions = new();
            configureOptions(binderOptions);
        
            if (binderOptions.BindNonPublicProperties)
            {
                throw new NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
            }
        
            return binderOptions;
        }

        public static int ParseInt(string value, string? path)
        {
            try
            {
                return int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
            }
            catch (Exception exception)
            {
                throw new InvalidOperationException($"Failed to convert configuration value at '{path}' to type '{typeof(int)}'.", exception);
            }
        }
        #endregion Core binding extensions.
    }
}
