﻿using System;
using System.Linq;
using Blog.DataAccess;
using Blog.DataAccess.Repositories;
using Blog.Model.DomainModels;
using Effort;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Blog.Tests.Repositories
{
	[TestClass]
	public class TagRepositoryTests : IDisposable
	{
		private TagRepository _repository;
		private ApplicationDbContext _context;
		private PostRepository _postRepository;
		[TestInitialize]
		public void Setup()
		{
			Effort.Provider.EffortProviderConfiguration.RegisterProvider();
			var connection = DbConnectionFactory.CreateTransient();
			_context = new ApplicationDbContext(connection, true);
			_repository = new TagRepository(_context);
			_postRepository = new PostRepository(_context);

		}
		[TestCleanup]
		public void Cleanup()
		{
			_context.Dispose();
		}
		[TestMethod]
		public void GetTagByName_retorna_a_tag_esperada()
		{
			var tag = _repository.Insert(new Tag { Name = "Tag 1" });
			_context.SaveChanges();
			var tagByName = _repository.GetTagByName("Tag 1");
			Assert.AreSame(tag, tagByName);
		}

		[TestMethod]
		public void GetTagByUrlFriendlyName_retorna_a_tag_esperada()
		{
			var tag = _repository.Insert(new Tag { Name = "Tag 1" });
			_context.SaveChanges();
			var tagByName = _repository.GetTagByUrlFriendlyName("tag-1");
			Assert.AreSame(tag, tagByName);
		}

		private void InsertPosts(bool publish)
		{
			for (int i = 0; i < 2; i++)
			{
				_postRepository.Insert(new Post { Body = "a", Title = "a",Publish = publish});
			}
			_context.SaveChanges();
		}

		private void InsertTags()
		{
			for (int i = 0; i < 2; i++)
			{
				_repository.Insert(new Tag { Name = "Tag " + i });
			}
			_context.SaveChanges();
		}

		private void AssociarTagsAPost()
		{
			var tagPostRepository = new TagPostRepository(_context);
			tagPostRepository.Insert(new TagPost { PostId = 2, TagId = 1 });
			tagPostRepository.Insert(new TagPost { PostId = 2, TagId = 2 });
			_context.SaveChanges();
		}

		[TestMethod]
		public void GetTagsFromPost_retorna_as_tags_esperadas()
		{
			InsertPosts(false);
			InsertTags();
			AssociarTagsAPost();

			var post = _postRepository.GetById(2);
			var tags = _repository.GetTagsFromPost(post);
			Assert.AreEqual(2, tags.Count());
		}

		[TestMethod]
		public void GetTagsInUse_retorna_as_tags_esperadas()
		{
			InsertPosts(true);
			InsertTags();
			InsertTags();
			AssociarTagsAPost();

			var tags = _repository.GetTagsInUse();
			Assert.AreEqual(2, tags.Count());
		}

		public void Dispose()
		{
			Dispose(true);
		}

		protected virtual void Dispose(bool dispose)
		{
			if (dispose)
			{
				_context.Dispose();
			}
		}
	}
}
