using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PageableTableApp.Controllers;
using Moq;
using NUnit.Framework;
using DomainModel;
using System.Web.Mvc;


namespace MvcTableDemo.Tests
{
    [TestFixture]
    public class ItemsListController_InitialList_Tests
    {
        IPersonsRepository _personsRepository;
        ItemsListController _itemsListController;


        [SetUp]
        public void SetUp ()
        {
            _personsRepository = PersonsRepositoryCreator.CreatePersonsRepository (10);

            _itemsListController = new ItemsListController (_personsRepository);
        }

        [Test]
        public void InitialList_Returns_Even_PageSizes_From_2_To_10 ()
        {
            var pageSize = 4;

            var result = _itemsListController.InitialList (pageSize, 2, "", "", "");

            Assert.IsNotNull (result, "View is not rendered.");

            var pageSizes = _itemsListController.ViewData ["pageSizes"] as List<SelectListItem>;

            Assert.AreEqual (5, pageSizes.Count, "Not all 5 page sizes were returned.");

            var areAllPageSizesIncluded = true;
            for (var i = 1; i <= 5; ++i)
                if (pageSizes [i - 1].Text != i * 2 + "")
                {
                    areAllPageSizesIncluded = false;

                    break;
                }
                else
                    if (i * 2 != pageSize)
                        Assert.IsFalse (pageSizes [i - 1].Selected, pageSizes[i - 1].Text + " was set as selected.");

            Assert.IsTrue (areAllPageSizesIncluded, "Not all page sizes were returned.");
            Assert.IsTrue (pageSizes [pageSize / 2 - 1].Selected, "Pagesize of " + pageSize + " was not selected.");
        }

        [Test]
        public void InitialList_Returns_Correct_Number_Of_Persons ()
        {
            var result = _itemsListController.InitialList (4, 2, "", "", "");

            Assert.IsNotNull (result, "View is not rendered.");

            Assert.AreEqual (_personsRepository.Persons.Count (), _itemsListController.ViewData ["numberOfRecords"]);
        }

        [Test]
        public void InitialList_Returns_Page_1_Of_3_Of_Size_4 ()
        {
            var result = _itemsListController.InitialList (4, 1, "", "", "");

            Assert.IsNotNull (result, "View is not rendered.");

            var returnedPersons = _itemsListController.ViewData.Model as IEnumerable<Object>;

            Assert.AreEqual(4, returnedPersons.Count(), "Not all persons were returned.");

            Assert.AreEqual (4, (int)_itemsListController.ViewData ["pageSize"]);
            Assert.AreEqual (3, (int)_itemsListController.ViewData ["pages"]);
            Assert.AreEqual (1, (int)_itemsListController.ViewData ["page"]);
        }

        [Test]
        public void InitialList_Returns_Page_2_Of_3_Of_Size_4_Sorted_By_Name_In_Ascending_Order ()
        {
            var result = _itemsListController.InitialList (4, 2, "name", "asc", "");

            Assert.IsNotNull (result, "View is not rendered.");

            var returnedPersons = _itemsListController.ViewData.Model as IEnumerable<Object>;

            Assert.AreEqual (4, returnedPersons.Count (), "Not all persons were returned.");

            Assert.AreEqual (4, (int)_itemsListController.ViewData ["pageSize"]);
            Assert.AreEqual (3, (int)_itemsListController.ViewData ["pages"]);
            Assert.AreEqual (2, (int)_itemsListController.ViewData ["page"]);

            var sortedPersons = _personsRepository.Persons.OrderBy (x => x.Name);

            var isSortOk = true;

            for (var i = 4; i < 8; ++i)
                if (sortedPersons.ElementAt(i).Name != (returnedPersons.ElementAt (i - 4)as Person).Name)
                {
                    isSortOk = false;

                    break;
                }

            Assert.IsTrue (isSortOk, "Sorting by name in ascending order has failed.");
        }

        [Test]
        public void InitialList_Returns_Page_2_Of_3_Of_Size_4_Sorted_By_Name_In_Descending_Order ()
        {
            var result = _itemsListController.InitialList (4, 2, "name", "desc", "");

            Assert.IsNotNull (result, "View is not rendered.");

            var returnedPersons = _itemsListController.ViewData.Model as IEnumerable<Object>;

            Assert.AreEqual (4, returnedPersons.Count (), "Not all persons were returned.");

            Assert.AreEqual (4, (int)_itemsListController.ViewData ["pageSize"]);
            Assert.AreEqual (3, (int)_itemsListController.ViewData ["pages"]);
            Assert.AreEqual (2, (int)_itemsListController.ViewData ["page"]);

            var sortedPersons = _personsRepository.Persons.OrderByDescending (x => x.Name);

            var isSortOk = true;

            for (var i = 4; i < 8; ++i)
                if (sortedPersons.ElementAt (i).Name != (returnedPersons.ElementAt (i - 4) as Person).Name)
                {
                    isSortOk = false;

                    break;
                }

            Assert.IsTrue (isSortOk, "Sorting by name in descending order has failed.");
        }

        [Test]
        public void InitialList_Returns_Persons_Filtered_By_Name_Name0_And_Name1 ()
        {
            var result = _itemsListController.InitialList (4, 1, "", "", "name:name0,name1");

            Assert.IsNotNull (result, "View is not rendered.");

            var returnedPersons = _itemsListController.ViewData.Model as IEnumerable<Object>;

            Assert.AreEqual (2, returnedPersons.Count (), "Not all persons were returned.");

            Assert.AreEqual (4, (int)_itemsListController.ViewData ["pageSize"]);
            Assert.AreEqual (1, (int)_itemsListController.ViewData ["pages"]);
            Assert.AreEqual (1, (int)_itemsListController.ViewData ["page"]);

            var p1 = returnedPersons.ElementAt (0) as Person;
            var p2 = returnedPersons.ElementAt (1) as Person;

            Assert.AreEqual ("Name0", p1.Name, "Person with name of Name0 was not returned.");
            Assert.AreEqual ("Name1", p2.Name, "Person with name of Name1 was not returned.");
        }

        [Test]
        public void InitialList_Returns_Persons_Filtered_By_Id_1_And_2_IsMarried_By_True ()
        {
            var result = _itemsListController.InitialList (4, 1, "", "", "id:1,2,ismarried:true");

            Assert.IsNotNull (result, "View is not rendered.");

            var returnedPersons = _itemsListController.ViewData.Model as IEnumerable<Object>;

            Assert.AreEqual (1, returnedPersons.Count (), "Not all persons were returned.");

            Assert.AreEqual (4, (int)_itemsListController.ViewData ["pageSize"]);
            Assert.AreEqual (1, (int)_itemsListController.ViewData ["pages"]);
            Assert.AreEqual (1, (int)_itemsListController.ViewData ["page"]);

            var p = returnedPersons.ElementAt (0) as Person;

            Assert.AreEqual (1, p.ID, "Person with ID of 1 was not returned.");
            Assert.AreEqual (true, p.IsMarried, "Person with IsMarried of true was not returned.");
        }
    }
}

//Assert.AreEqual (itemsListController.ViewData ["filters"]
//Assert.AreEqual ("", itemsListController.ViewData ["showFilter"]);

//            Assert.AreEqual (itemsListController.ViewData ["sortBy"] );
//            Assert.AreEqual ( itemsListController.ViewData ["sortMode"]);
