// Copyright 2007-2008 The Apache Software Foundation.
//  
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use 
// this file except in compliance with the License. You may obtain a copy of the 
// License at 
// 
//     http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software distributed 
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
// specific language governing permissions and limitations under the License.
namespace MassTransit.Tests.Saga.Locator
{
	using System;
	using System.Diagnostics;
	using System.Linq;
	using System.Linq.Expressions;
	using Magnum;
	using MassTransit.Saga;
	using MassTransit.Saga.Pipeline;
	using NUnit.Framework;
	using Util;

	[TestFixture]
	public class SagaExpression_Specs
	{
		private Guid _sagaId;
		private InitiateSimpleSaga _initiateSaga;
		private InMemorySagaRepository<SimpleSaga> _repository;
		private Guid _otherSagaId;
		private ObservableSagaMessage _observeSaga;
		private InitiateSimpleSaga _initiateOtherSaga;

		[SetUp]
		public void Setup()
		{
			_repository = new InMemorySagaRepository<SimpleSaga>();
			var initiatePolicy = new InitiatingSagaPolicy<SimpleSaga,InitiateSimpleSaga>(x => false);

			_sagaId = CombGuid.Generate();
			_initiateSaga = new InitiateSimpleSaga { CorrelationId = _sagaId, Name = "Chris" };
			_repository.Send(x => x.CorrelationId == _sagaId, initiatePolicy, _initiateSaga, saga => saga.Consume(_initiateSaga));

			_initiateOtherSaga = new InitiateSimpleSaga {CorrelationId = _otherSagaId, Name = "Dru"};

			_otherSagaId = Guid.NewGuid();
			_repository.Send(x => x.CorrelationId == _otherSagaId, initiatePolicy, _initiateOtherSaga, saga => saga.Consume(_initiateOtherSaga));
	
			_observeSaga = new ObservableSagaMessage {Name = "Chris"};
		}

		[Test]
		public void The_saga_expression_should_be_converted_down_to_a_saga_only_filter()
		{
			Expression<Func<SimpleSaga, InitiateSimpleSaga, bool>> selector = (s, m) => s.CorrelationId == m.CorrelationId;

			var filter = new SagaFilterExpressionConverter<SimpleSaga, InitiateSimpleSaga>(_initiateSaga).Convert(selector);
			Trace.WriteLine(filter.ToString());

			var matches = _repository.Where(filter);

			Assert.AreEqual(1, matches.Count());
		}

		[Test]
		public void Matching_by_property_should_be_happy()
		{
			Expression<Func<SimpleSaga, ObservableSagaMessage, bool>> selector = (s, m) => s.Name == m.Name;

			var filter = new SagaFilterExpressionConverter<SimpleSaga, ObservableSagaMessage>(_observeSaga).Convert(selector);
			Trace.WriteLine(filter.ToString());

			var matches = _repository.Where(filter);

			Assert.AreEqual(1, matches.Count());
		}
	}
}