using System;
using System.Collections.Generic;

namespace System.Reactive.Joins
{
	internal class Plan<T1, TResult> : Plan<TResult>
	{
		internal Pattern<T1> Expression { get; }

		internal Func<T1, TResult> Selector { get; }

		internal Plan(Pattern<T1> expression, Func<T1, TResult> selector)
		{
			this.Expression = expression;
			this.Selector = selector;
		}

		internal override ActivePlan Activate(Dictionary<object, IJoinObserver> externalSubscriptions, IObserver<TResult> observer, Action<ActivePlan> deactivate)
		{
			Action<Exception> action = new Action<Exception>(observer.OnError);
			JoinObserver<T1> firstJoinObserver = Plan<TResult>.CreateObserver<T1>(externalSubscriptions, this.Expression.First, action);
			ActivePlan<T1> activePlan = null;
			activePlan = new ActivePlan<T1>(firstJoinObserver, delegate(T1 first)
			{
				TResult tresult;
				try
				{
					tresult = this.Selector(first);
				}
				catch (Exception ex)
				{
					observer.OnError(ex);
					return;
				}
				observer.OnNext(tresult);
			}, delegate
			{
				firstJoinObserver.RemoveActivePlan(activePlan);
				deactivate(activePlan);
			});
			firstJoinObserver.AddActivePlan(activePlan);
			return activePlan;
		}
	}
}
