ReloadableComponent
using Polly.Telemetry;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Polly.Utils.Pipeline
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal sealed class ReloadableComponent : PipelineComponent
    {
        [System.Runtime.CompilerServices.Nullable(0)]
        internal sealed class ReloadFailedArguments : IEquatable<ReloadFailedArguments>
        {
            [CompilerGenerated]
            private Type EqualityContract {
                [CompilerGenerated]
                get {
                    return typeof(ReloadFailedArguments);
                }
            }
            public Exception Exception { get; set; }
            public ReloadFailedArguments(Exception Exception)
            {
                Exception = Exception;
                base..ctor();
            }
            [CompilerGenerated]
            public override string ToString()
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("ReloadFailedArguments");
                stringBuilder.Append(" { ");
                if (PrintMembers(stringBuilder))
                    stringBuilder.Append(' ');
                stringBuilder.Append('}');
                return stringBuilder.ToString();
            }
            [CompilerGenerated]
            private bool PrintMembers(StringBuilder builder)
            {
                RuntimeHelpers.EnsureSufficientExecutionStack();
                builder.Append("Exception = ");
                builder.Append(Exception);
                return true;
            }
            public static bool operator !=(ReloadFailedArguments left, ReloadFailedArguments right)
            {
                return !(left == right);
            }
            public static bool operator ==(ReloadFailedArguments left, ReloadFailedArguments right)
            {
                if ((object)left != right)
                    return left?.Equals(right) ?? false;
                return true;
            }
            [CompilerGenerated]
            public override int GetHashCode()
            {
                return EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<Exception>.Default.GetHashCode(Exception);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public override bool Equals(object obj)
            {
                return Equals(obj as ReloadFailedArguments);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public bool Equals(ReloadFailedArguments other)
            {
                if ((object)this != other) {
                    if ((object)other != null && EqualityContract == other.EqualityContract)
                        return EqualityComparer<Exception>.Default.Equals(Exception, other.Exception);
                    return false;
                }
                return true;
            }
            [CompilerGenerated]
            private ReloadFailedArguments(ReloadFailedArguments original)
            {
                Exception = original.Exception;
            }
            [CompilerGenerated]
            public void Deconstruct(out Exception Exception)
            {
                Exception = this.Exception;
            }
        }
        [System.Runtime.CompilerServices.Nullable(0)]
        internal sealed class DisposedFailedArguments : IEquatable<DisposedFailedArguments>
        {
            [CompilerGenerated]
            private Type EqualityContract {
                [CompilerGenerated]
                get {
                    return typeof(DisposedFailedArguments);
                }
            }
            public Exception Exception { get; set; }
            public DisposedFailedArguments(Exception Exception)
            {
                Exception = Exception;
                base..ctor();
            }
            [CompilerGenerated]
            public override string ToString()
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("DisposedFailedArguments");
                stringBuilder.Append(" { ");
                if (PrintMembers(stringBuilder))
                    stringBuilder.Append(' ');
                stringBuilder.Append('}');
                return stringBuilder.ToString();
            }
            [CompilerGenerated]
            private bool PrintMembers(StringBuilder builder)
            {
                RuntimeHelpers.EnsureSufficientExecutionStack();
                builder.Append("Exception = ");
                builder.Append(Exception);
                return true;
            }
            public static bool operator !=(DisposedFailedArguments left, DisposedFailedArguments right)
            {
                return !(left == right);
            }
            public static bool operator ==(DisposedFailedArguments left, DisposedFailedArguments right)
            {
                if ((object)left != right)
                    return left?.Equals(right) ?? false;
                return true;
            }
            [CompilerGenerated]
            public override int GetHashCode()
            {
                return EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<Exception>.Default.GetHashCode(Exception);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public override bool Equals(object obj)
            {
                return Equals(obj as DisposedFailedArguments);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public bool Equals(DisposedFailedArguments other)
            {
                if ((object)this != other) {
                    if ((object)other != null && EqualityContract == other.EqualityContract)
                        return EqualityComparer<Exception>.Default.Equals(Exception, other.Exception);
                    return false;
                }
                return true;
            }
            [CompilerGenerated]
            private DisposedFailedArguments(DisposedFailedArguments original)
            {
                Exception = original.Exception;
            }
            [CompilerGenerated]
            public void Deconstruct(out Exception Exception)
            {
                Exception = this.Exception;
            }
        }
        [System.Runtime.CompilerServices.Nullable(0)]
        internal sealed class OnReloadArguments : IEquatable<OnReloadArguments>
        {
            [CompilerGenerated]
            private Type EqualityContract {
                [CompilerGenerated]
                get {
                    return typeof(OnReloadArguments);
                }
            }
            public OnReloadArguments()
            {
            }
            [CompilerGenerated]
            public override string ToString()
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("OnReloadArguments");
                stringBuilder.Append(" { ");
                if (PrintMembers(stringBuilder))
                    stringBuilder.Append(' ');
                stringBuilder.Append('}');
                return stringBuilder.ToString();
            }
            [CompilerGenerated]
            private bool PrintMembers(StringBuilder builder)
            {
                return false;
            }
            public static bool operator !=(OnReloadArguments left, OnReloadArguments right)
            {
                return !(left == right);
            }
            public static bool operator ==(OnReloadArguments left, OnReloadArguments right)
            {
                if ((object)left != right)
                    return left?.Equals(right) ?? false;
                return true;
            }
            [CompilerGenerated]
            public override int GetHashCode()
            {
                return EqualityComparer<Type>.Default.GetHashCode(EqualityContract);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public override bool Equals(object obj)
            {
                return Equals(obj as OnReloadArguments);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public bool Equals(OnReloadArguments other)
            {
                if ((object)this != other) {
                    if ((object)other != null)
                        return EqualityContract == other.EqualityContract;
                    return false;
                }
                return true;
            }
            [CompilerGenerated]
            private OnReloadArguments(OnReloadArguments original)
            {
            }
        }
        [System.Runtime.CompilerServices.Nullable(0)]
        internal sealed class Entry : IEquatable<Entry>
        {
            [CompilerGenerated]
            private Type EqualityContract {
                [CompilerGenerated]
                get {
                    return typeof(Entry);
                }
            }
            public PipelineComponent Component { get; set; }
            public List<CancellationToken> ReloadTokens { get; set; }
            public ResilienceStrategyTelemetry Telemetry { get; set; }
            public Entry(PipelineComponent Component, List<CancellationToken> ReloadTokens, ResilienceStrategyTelemetry Telemetry)
            {
                Component = Component;
                ReloadTokens = ReloadTokens;
                Telemetry = Telemetry;
                base..ctor();
            }
            [CompilerGenerated]
            public override string ToString()
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.Append("Entry");
                stringBuilder.Append(" { ");
                if (PrintMembers(stringBuilder))
                    stringBuilder.Append(' ');
                stringBuilder.Append('}');
                return stringBuilder.ToString();
            }
            [CompilerGenerated]
            private bool PrintMembers(StringBuilder builder)
            {
                RuntimeHelpers.EnsureSufficientExecutionStack();
                builder.Append("Component = ");
                builder.Append(Component);
                builder.Append(", ReloadTokens = ");
                builder.Append(ReloadTokens);
                builder.Append(", Telemetry = ");
                builder.Append(Telemetry);
                return true;
            }
            public static bool operator !=(Entry left, Entry right)
            {
                return !(left == right);
            }
            public static bool operator ==(Entry left, Entry right)
            {
                if ((object)left != right)
                    return left?.Equals(right) ?? false;
                return true;
            }
            [CompilerGenerated]
            public override int GetHashCode()
            {
                return ((EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<PipelineComponent>.Default.GetHashCode(Component)) * -1521134295 + EqualityComparer<List<CancellationToken>>.Default.GetHashCode(ReloadTokens)) * -1521134295 + EqualityComparer<ResilienceStrategyTelemetry>.Default.GetHashCode(Telemetry);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public override bool Equals(object obj)
            {
                return Equals(obj as Entry);
            }
            [System.Runtime.CompilerServices.NullableContext(2)]
            [CompilerGenerated]
            public bool Equals(Entry other)
            {
                if ((object)this != other) {
                    if ((object)other != null && EqualityContract == other.EqualityContract && EqualityComparer<PipelineComponent>.Default.Equals(Component, other.Component) && EqualityComparer<List<CancellationToken>>.Default.Equals(ReloadTokens, other.ReloadTokens))
                        return EqualityComparer<ResilienceStrategyTelemetry>.Default.Equals(Telemetry, other.Telemetry);
                    return false;
                }
                return true;
            }
            [CompilerGenerated]
            private Entry(Entry original)
            {
                Component = original.Component;
                ReloadTokens = original.ReloadTokens;
                Telemetry = original.Telemetry;
            }
            [CompilerGenerated]
            public void Deconstruct(out PipelineComponent Component, out List<CancellationToken> ReloadTokens, out ResilienceStrategyTelemetry Telemetry)
            {
                Component = this.Component;
                ReloadTokens = this.ReloadTokens;
                Telemetry = this.Telemetry;
            }
        }
        public const string ReloadFailedEvent = "ReloadFailed";
        public const string DisposeFailedEvent = "DisposeFailed";
        public const string OnReloadEvent = "OnReload";
        private readonly Func<Entry> _factory;
        private ResilienceStrategyTelemetry _telemetry;
        private CancellationTokenSource _tokenSource;
        private CancellationTokenRegistration _registration;
        private List<CancellationToken> _reloadTokens;
        public PipelineComponent Component { get; set; }
        public ReloadableComponent(Entry entry, Func<Entry> factory)
        {
            Component = entry.Component;
            _reloadTokens = entry.ReloadTokens;
            _factory = factory;
            _telemetry = entry.Telemetry;
            TryRegisterOnReload();
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            0,
            1
        })]
        internal override ValueTask<Outcome<TResult>> ExecuteCore<[System.Runtime.CompilerServices.Nullable(2)] TResult, [System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            1,
            1,
            0,
            0,
            1
        })] Func<ResilienceContext, TState, ValueTask<Outcome<TResult>>> callback, ResilienceContext context, TState state)
        {
            return Component.ExecuteCore(callback, context, state);
        }
        public override ValueTask DisposeAsync()
        {
            DisposeRegistration();
            return Component.DisposeAsync();
        }
        private void TryRegisterOnReload()
        {
            if (_reloadTokens.Count != 0) {
                _tokenSource = CancellationTokenSource.CreateLinkedTokenSource(_reloadTokens.ToArray());
                _registration = _tokenSource.Token.Register(delegate {
                    ResilienceContext context = ResilienceContextPool.Shared.Get(default(CancellationToken)).Initialize<VoidResult>(true);
                    PipelineComponent component = this.Component;
                    try {
                        _telemetry.Report(new ResilienceEvent(ResilienceEventSeverity.Information, "OnReload"), context, new OnReloadArguments());
                        _factory().Deconstruct(out PipelineComponent Component, out List<CancellationToken> ReloadTokens, out ResilienceStrategyTelemetry Telemetry);
                        this.Component = Component;
                        _reloadTokens = ReloadTokens;
                        _telemetry = Telemetry;
                    } catch (Exception exception) {
                        _reloadTokens = new List<CancellationToken>();
                        _telemetry.Report(new ResilienceEvent(ResilienceEventSeverity.Error, "ReloadFailed"), context, Outcome.FromException(exception), new ReloadFailedArguments(exception));
                        ResilienceContextPool.Shared.Return(context);
                    }
                    DisposeRegistration();
                    TryRegisterOnReload();
                    DisposeDiscardedComponentSafeAsync(component);
                });
            }
        }
        [AsyncStateMachine(typeof(<DisposeDiscardedComponentSafeAsync>d__16))]
        private Task DisposeDiscardedComponentSafeAsync(PipelineComponent component)
        {
            <DisposeDiscardedComponentSafeAsync>d__16 stateMachine = default(<DisposeDiscardedComponentSafeAsync>d__16);
            stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
            stateMachine.<>4__this = this;
            stateMachine.component = component;
            stateMachine.<>1__state = -1;
            stateMachine.<>t__builder.Start(ref stateMachine);
            return stateMachine.<>t__builder.Task;
        }
        private void DisposeRegistration()
        {
            _registration.Dispose();
            _tokenSource.Dispose();
        }
    }
}