using System;
using System.Reactive.Disposables;

namespace System.Reactive
{
	internal sealed class AutoDetachObserver<T> : ObserverBase<T>, ISafeObserver<T>, IObserver<T>, IDisposable
	{
		public AutoDetachObserver(IObserver<T> observer)
		{
			this._observer = observer;
		}

		public void SetResource(IDisposable resource)
		{
			Disposable.SetSingle(ref this._disposable, resource);
		}

		protected override void OnNextCore(T value)
		{
			bool flag = false;
			try
			{
				this._observer.OnNext(value);
				flag = true;
			}
			finally
			{
				if (!flag)
				{
					base.Dispose();
				}
			}
		}

		protected override void OnErrorCore(Exception exception)
		{
			try
			{
				this._observer.OnError(exception);
			}
			finally
			{
				base.Dispose();
			}
		}

		protected override void OnCompletedCore()
		{
			try
			{
				this._observer.OnCompleted();
			}
			finally
			{
				base.Dispose();
			}
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (disposing)
			{
				Disposable.TryDispose(ref this._disposable);
			}
		}

		private readonly IObserver<T> _observer;

		private IDisposable _disposable;
	}
}
