using System;

namespace System.Reactive
{
	public sealed class AnonymousObserver<T> : ObserverBase<T>
	{
		public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
		{
			if (onNext == null)
			{
				throw new ArgumentNullException("onNext");
			}
			this._onNext = onNext;
			if (onError == null)
			{
				throw new ArgumentNullException("onError");
			}
			this._onError = onError;
			if (onCompleted == null)
			{
				throw new ArgumentNullException("onCompleted");
			}
			this._onCompleted = onCompleted;
		}

		public AnonymousObserver(Action<T> onNext)
			: this(onNext, Stubs.Throw, Stubs.Nop)
		{
		}

		public AnonymousObserver(Action<T> onNext, Action<Exception> onError)
			: this(onNext, onError, Stubs.Nop)
		{
		}

		public AnonymousObserver(Action<T> onNext, Action onCompleted)
			: this(onNext, Stubs.Throw, onCompleted)
		{
		}

		protected override void OnNextCore(T value)
		{
			this._onNext(value);
		}

		protected override void OnErrorCore(Exception error)
		{
			this._onError(error);
		}

		protected override void OnCompletedCore()
		{
			this._onCompleted();
		}

		internal ISafeObserver<T> MakeSafe()
		{
			return new AnonymousSafeObserver<T>(this._onNext, this._onError, this._onCompleted);
		}

		private readonly Action<T> _onNext;

		private readonly Action<Exception> _onError;

		private readonly Action _onCompleted;
	}
}
