using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using test.Models.Abstract;
using test.Models.Entities;
using test.Controllers;
using test.Models.ViewModel;
using test.Models.Concrete;
using System.Web.Mvc;
using System.Web;

namespace testy
{
    /// <summary>
    /// Summary description for ProductsTest
    /// </summary>
    [TestClass]
    public class ProductsTest
    {
        public ProductsTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        [TestMethod]
        public void WyswietlenieWszystkichProduktow()
        {
            // arrange
            // tworzymy repozytorium mock (cos jak obiekt interfejsu)
            Mock<IProductRepository> mock = new Mock<IProductRepository>();
            mock.Setup(x => x.Products).Returns(new Product[] {
                new Product { Id=1, Name="nazwa1"},
                new Product { Id=2, Name="nazwa2"},
                new Product { Id=3, Name="nazwa3"}
            }.AsQueryable());

            ProductController controller = new ProductController(mock.Object);

            // action
            Product[] result = ((ProductView)((ViewResultBase)controller.Products()).Model).Products.ToArray();

            // assert
            // sprawdzamy czy zwrocil wszystkie produkty
            Assert.AreEqual(mock.Object.Products.Count(), result.Length);
            Assert.AreEqual("nazwa1", result[0].Name);
            Assert.AreEqual("nazwa2", result[1].Name);
            Assert.AreEqual("nazwa3", result[2].Name);
        }

        [TestMethod]
        public void WyswietlenieWgNazwy()
        {
             // arrange
            // tworzymy repozytorium mock (cos jak obiekt interfejsu)
            Mock<IProductRepository> mock = new Mock<IProductRepository>();
            mock.Setup(x => x.Products).Returns(new Product[] {
                new Product { Id=1, Name="c"},
                new Product { Id=2, Name="d"},
                new Product { Id=3, Name="b"}
            }.AsQueryable());

            ProductController controller = new ProductController(mock.Object);

            //action
            Product[] result = ((ProductView)((ViewResultBase)controller.ProductsSortByName()).Model).Products.ToArray();

            //asserts
            Assert.AreEqual(mock.Object.Products.Count(), result.Length);
            Assert.AreEqual("b", result[0].Name);
            Assert.AreEqual("c", result[1].Name);
            Assert.AreEqual("d", result[2].Name);
        }

        [TestMethod]
        public void DodanieProduktuDoBazyXML()
        {
            // arrange
            string path=@"D:\IS\Programowanie\ASP\test\test\Resources\produkty.xml";
            // tworzymy repozytorium XML
            XMLProductRepository repo=new XMLProductRepository(path);
            // tworzymy obiekt productController dajac w konstruktorze baze xml
            ProductController controller = new ProductController(repo);

            // w maire losowa cena
            Random r = new Random();
            int price = r.Next();

            // tworzymy nowy produkt
            Product p = new Product
            {
                Name="produkt1",
                Description="opis1",
                Price=Convert.ToDecimal(price)
            };

            // act
            // dodajemy product
            controller.AddProduct(p);

            // asserts
            // sprawdzamy czy dodal sie tym co zwrocil widok normalnego wyswietlania produktow
            Product[] result = ((ProductView)((ViewResultBase)controller.Products()).Model).Products.ToArray();
            Assert.AreEqual(p, result[result.Length - 1]);
            // sprawdzamy czy dodal sie do bazy
            XMLProductRepository repoAfter = new XMLProductRepository(path);
            Assert.AreEqual(p.Name, repoAfter.Products.Last(x => x.Name == "produkt1").Name);
            Assert.AreEqual(p.Description, repoAfter.Products.Last(x => x.Name == "produkt1").Description);
            Assert.AreEqual(p.Price, repoAfter.Products.Last(x => x.Name == "produkt1").Price);
        }
        
    }
}
