using System;

namespace System.Reactive.Linq.ObservableImpl
{
	internal sealed class Dematerialize<TSource> : Producer<TSource, Dematerialize<TSource>._>
	{
		public Dematerialize(IObservable<Notification<TSource>> source)
		{
			this._source = source;
		}

		protected override Dematerialize<TSource>._ CreateSink(IObserver<TSource> observer)
		{
			return new Dematerialize<TSource>._(observer);
		}

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

		private readonly IObservable<Notification<TSource>> _source;

		internal sealed class _ : Sink<Notification<TSource>, TSource>
		{
			public _(IObserver<TSource> observer)
				: base(observer)
			{
			}

			public override void OnNext(Notification<TSource> value)
			{
				switch (value.Kind)
				{
				case NotificationKind.OnNext:
					base.ForwardOnNext(value.Value);
					return;
				case NotificationKind.OnError:
					base.ForwardOnError(value.Exception);
					return;
				case NotificationKind.OnCompleted:
					base.ForwardOnCompleted();
					return;
				default:
					return;
				}
			}
		}
	}
}
