using System;
using NUnit.Framework;
using DotNetMock;
using DotNetMock.Framework.Data;
using System.Data;
using System.Data.SqlClient;

namespace DotNetMock.Framework.Tests.Data
{
	[TestFixture]
	public class MockDataParameterCollectionTests
	{
		private MockDataParameterCollection _mockDataParameterCollection = null;

		[SetUp]
		public void Init()
		{
			_mockDataParameterCollection = new MockDataParameterCollection();
		}

		[TearDown]
		public void Destroy()
		{
			_mockDataParameterCollection = null;
		}

		[Test]
		public void AddOneParameter()
		{
			MockDataParameter mockDP1 = new MockDataParameter("@inpID", "123456");
			
			_mockDataParameterCollection.AddExpected(mockDP1);
			_mockDataParameterCollection.Add(mockDP1);
			_mockDataParameterCollection.Verify();
		}

		[Test]
		public void AddParameterWithValueAsInt()
		{
			MockDataParameter mockDP1 = new MockDataParameter("@inpID", 123456);
			
			_mockDataParameterCollection.AddExpected(mockDP1);
			_mockDataParameterCollection.Add(mockDP1);
			_mockDataParameterCollection.Verify();
		}

		[Test]
		[ExpectedException(typeof(AssertionException))]
		public void AddParameterWithUnexpectedType()
		{
			MockDataParameter mockDP1 = new MockDataParameter("@inpID", 123456);
			MockDataParameter mockDP2 = new MockDataParameter("@inpID", "123456");
			
			_mockDataParameterCollection.AddExpected(mockDP1);
			_mockDataParameterCollection.Add(mockDP2);
			_mockDataParameterCollection.Verify();
		}

		[Test]
		public void TestToExposeTheMockDataParameterDefaultTypeProblem()
		{
			MockDataParameter pageSizeParam = new MockDataParameter("@pageSize", 5);
			pageSizeParam.SetExpectedType(DbType.Int32);

			MockCommand command = new MockCommand();
			command.SetExpectedParameter(pageSizeParam);
			
			MockDbConnection con = new MockDbConnection();
			con.SetExpectedCommand(command);
			
			IDbCommand com = con.CreateCommand();
			IDataParameter realPageSizeParam = new SqlParameter("@pageSize", 5);
			com.Parameters.Add(realPageSizeParam);
			
			command.Parameters.Verify();
		}

		[Test]
		public void AddMultipleParameters()
		{
			MockDataParameter mockDP1 = new MockDataParameter("@inpID", "123456");
			MockDataParameter mockDP2 = new MockDataParameter("@password", "mock");
			_mockDataParameterCollection.AddExpected(mockDP1);
			_mockDataParameterCollection.AddExpected(mockDP2);
			_mockDataParameterCollection.Add(new MockDataParameter("@inpID", "123456"));
			_mockDataParameterCollection.Add(new MockDataParameter("@password", "mock"));
			_mockDataParameterCollection.Verify();
		}
		[Test]
		public void AddNewParameterStringValue()
		{
			_mockDataParameterCollection.Add("@inpID", "123456");
			MockDataParameter mockDP = new MockDataParameter("@inpID", "123456");
			_mockDataParameterCollection.AddExpected(mockDP);
			_mockDataParameterCollection.Verify();
		}
		[Test]
		public void AddNewParameterNameType()
		{
			_mockDataParameterCollection.Add("@inpID", DbType.String);
			MockDataParameter mockDP = new MockDataParameter("@inpID", DbType.String);
			_mockDataParameterCollection.AddExpected(mockDP);
			_mockDataParameterCollection.Verify();
		}
		[Test]
		public void ValidContains()
		{
			_mockDataParameterCollection.Add("@inpID", "123456");
			Assert.IsTrue(_mockDataParameterCollection.Contains("@inpID"), "Parameter @inpID not found - First");
			_mockDataParameterCollection.Add("@inpPassword", "password");
			Assert.IsTrue( _mockDataParameterCollection.Contains("@inpID"), "Parameter @inpID not found - Second");
			Assert.IsTrue( _mockDataParameterCollection.Contains("@inpPassword"), "Parameter @inpPassword not found");

		}
		[Test]
		public void InValidContains()
		{
			IDataParameter mockDP = _mockDataParameterCollection.Add("@inpID", "123456");
			Assert.IsTrue(!_mockDataParameterCollection.Contains("@inpPassword"));
		}
		[Test]
		public void ValidRemoveAt()
		{
			_mockDataParameterCollection.Add("@inpID", "123456");
			_mockDataParameterCollection.Add("@inpPassword", "password");
			Assert.IsTrue(_mockDataParameterCollection.Contains("@inpID"));
			Assert.IsTrue(_mockDataParameterCollection.Contains("@inpPassword"));
			_mockDataParameterCollection.RemoveAt("@inpID");
			Assert.IsTrue(!_mockDataParameterCollection.Contains("@inpID"));
			Assert.IsTrue(_mockDataParameterCollection.Contains("@inpPassword"));
		}
		[Test]
		[ExpectedException(typeof(ApplicationException))]
		public void InValidRemoveAt()
		{
			IDataParameter mockDP = _mockDataParameterCollection.Add("@inpID", "123456");
			_mockDataParameterCollection.RemoveAt("@inpPassword");
		}
		[Test]
		public void IndexOf()
		{
			_mockDataParameterCollection.Add("@inpID", "123456");
			_mockDataParameterCollection.Add("@inpPassword", "password");
			_mockDataParameterCollection.Add("@inpThird", "third");
			Assert.AreEqual( 1, _mockDataParameterCollection.IndexOf("@inpPassword"), "Indexes do not equal");
			Assert.AreEqual( 0, _mockDataParameterCollection.IndexOf("@inpID"), "Indexes do not equal");
		}
		[Test]
		[ExpectedException(typeof(ApplicationException))]
		public void InValidIndexOf()
		{
			IDataParameter mockDP = _mockDataParameterCollection.Add("@inpID", "123456");
			IDataParameter mockDP1 = _mockDataParameterCollection.Add("@inpPassword", "password");
			IDataParameter mockDP2 = _mockDataParameterCollection.Add("@inpThird", "third");
			Assert.AreEqual(4, _mockDataParameterCollection.IndexOf("@inpFake"), "Index not found");
		}
		[Test]
		public void ValidIndexer()
		{
			MockDataParameter mockDP = new MockDataParameter("@inpID", "123456");
			_mockDataParameterCollection.Add(mockDP);
			Assert.AreEqual( mockDP, _mockDataParameterCollection["@inpID"], "Parameters not equal");
		}
		[Test]
		[ExpectedException(typeof(ApplicationException))]
		public void InValidIndexer()
		{
			MockDataParameter mockDP = new MockDataParameter("@inpID", "654321");
			_mockDataParameterCollection.Add(mockDP);
			Assert.AreEqual( mockDP, _mockDataParameterCollection["@inpPadssword"], "Parameters not equal");
		}
		[Test]
		[ExpectedException(typeof(NotImplementedException))]
		public void InValidInsert()
		{
			_mockDataParameterCollection.Insert(3, "fake");
		}
		[Test]
		[ExpectedException(typeof(NotImplementedException))]
		public void InValidIListIndexOf()
		{
			object badValue = new object();
			int index = _mockDataParameterCollection.IndexOf(badValue);
		}
		[Test]
		[ExpectedException(typeof(NotImplementedException))]
		public void InValidRemove()
		{
			object badValue = new object();
			_mockDataParameterCollection.Remove(badValue);
		}
		[Test]
		[ExpectedException(typeof(NotImplementedException))]
		public void InValidIListContains()
		{
			object badValue = new object();
			_mockDataParameterCollection.Contains(badValue);
		}
	}
}
