using System;
using System.Reactive.Disposables;

namespace System.Reactive.Linq.ObservableImpl
{
	internal class AddRef<TSource> : Producer<TSource, AddRef<TSource>._>
	{
		public AddRef(IObservable<TSource> source, RefCountDisposable refCount)
		{
			this._source = source;
			this._refCount = refCount;
		}

		protected override AddRef<TSource>._ CreateSink(IObserver<TSource> observer)
		{
			return new AddRef<TSource>._(observer, this._refCount.GetDisposable());
		}

		protected override void Run(AddRef<TSource>._ sink)
		{
			sink.Run(this._source);
		}

		private readonly IObservable<TSource> _source;

		private readonly RefCountDisposable _refCount;

		internal sealed class _ : IdentitySink<TSource>
		{
			public _(IObserver<TSource> observer, IDisposable refCountDisposable)
				: base(observer)
			{
				this._refCountDisposable = refCountDisposable;
			}

			protected override void Dispose(bool disposing)
			{
				if (disposing)
				{
					this._refCountDisposable.Dispose();
				}
				base.Dispose(disposing);
			}

			private readonly IDisposable _refCountDisposable;
		}
	}
}
