using System.Xml;
using MusicMetaTagger.Client.AllMusicGuide.RemoteDataAccess.Parser;
using MusicMetaTagger.Client.AllMusicGuide.Services;
using MusicMetaTagger.Core.Model;
using MusicMetaTagger.Core.Services;
using NSubstitute;
using NUnit.Framework;

namespace MusicMetaTagger.Client.AllMusicGuide.Tests.Services
{
	[TestFixture]
	public class TrackRaterTests
	{
		private IMusicGuide _musicGuide;
		private Album _abbeyRoad;
		private Artist _beatles;
		private Album _killTheMoonLight;
		private Album _girlsCanTell;
		private Artist _spoon;
		private Album _reactor;
		private Artist _neilYoung;
		private Album _pulpFiction;
		private Album _wipersBoxSet;
		private Artist _wipers;

		private static TEntity LoadObj<TEntity, TParser>(string filename) where TParser : IParser<TEntity>, new()
		{
			var xml = new XmlDocument();
			xml.Load(filename);
			return new TParser().Parse(xml);
		}
		
		private static Artist LoadArtist(string filename)
		{
			var xml = new XmlDocument();
			xml.Load(filename);
			var artist = new ArtistParser().Parse(xml);
			artist.Discography = new ArtistDiscographyPageParser().Parse(xml);
			return artist;
		}

		[TestFixtureSetUp]
		public void SetUp()
		{
			_abbeyRoad = LoadObj<Album, AlbumParser>("Album-AbbeyRoad.xml");
			_killTheMoonLight = LoadObj<Album, AlbumParser>("Album-KillTheMoonLight.xml");
			_girlsCanTell = LoadObj<Album, AlbumParser>("Album-GirlsCanTell.xml");
			_reactor = LoadObj<Album, AlbumParser>("Album-Reactor.xml");
			_pulpFiction = LoadObj<Album, AlbumParser>("Album-PulpFiction.xml");
			_wipersBoxSet = LoadObj<Album, AlbumParser>("Album-WipersBoxSet.xml");

			_beatles = LoadArtist("Artist-Beatles.xml");
			_spoon = LoadArtist("Artist-Spoon.xml");
			_neilYoung = LoadArtist("Artist-NeilYoung.xml");

			var wipers = new XmlDocument();
			wipers.Load("Artist-Wipers.xml");
			_wipers = new ArtistParser().Parse(wipers);
			_wipers.Discography = new ArtistDiscographyPageParser().Parse(wipers);
			var wipersCompilations = new XmlDocument();
			wipersCompilations.Load("ArtistCompilations-Wipers.xml");
			_wipers.Discography.AddRange(new ArtistDiscographyPageParser().Parse(wipersCompilations));

			_musicGuide = Substitute.For<IMusicGuide>();
			_musicGuide.GetAlbum(_abbeyRoad.AlbumId).Returns(_abbeyRoad);
			_musicGuide.GetArtist(_beatles.ArtistId).Returns(_beatles);
			_musicGuide.GetAlbum(_girlsCanTell.AlbumId).Returns(_girlsCanTell);
			_musicGuide.GetAlbum(_killTheMoonLight.AlbumId).Returns(_killTheMoonLight);
			_musicGuide.GetArtist(_spoon.ArtistId).Returns(_spoon);
			_musicGuide.GetAlbum(_reactor.AlbumId).Returns(_reactor);
			_musicGuide.GetArtist(_neilYoung.ArtistId).Returns(_neilYoung);
			_musicGuide.GetAlbum(_pulpFiction.AlbumId).Returns(_pulpFiction);
			_musicGuide.GetAlbum(_wipersBoxSet.AlbumId).Returns(_wipersBoxSet);
			_musicGuide.GetArtist(_wipers.ArtistId).Returns(_wipers);
		}

		[Test]
		public void RateTrackTest()
		{
			var trackRater = new TrackRater(_musicGuide);

			Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[0]), Is.EqualTo(10));
			Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[1]), Is.EqualTo(10));
			Assert.That(trackRater.RateTrack(_abbeyRoad.Tracks[2]), Is.EqualTo(9));
			Assert.That(trackRater.RateTrack(_girlsCanTell.Tracks[0]), Is.EqualTo(10));
			Assert.That(trackRater.RateTrack(_girlsCanTell.Tracks[1]), Is.EqualTo(9));
			Assert.That(trackRater.RateTrack(_killTheMoonLight.Tracks[2]), Is.EqualTo(8));
			Assert.That(trackRater.RateTrack(_reactor.Tracks[0]), Is.EqualTo(6));
			Assert.That(trackRater.RateTrack(_reactor.Tracks[1]), Is.EqualTo(4));
			Assert.That(trackRater.RateTrack(_pulpFiction.Tracks[2]), Is.EqualTo(10));
			Assert.That(trackRater.RateTrack(_wipersBoxSet.Tracks[0]), Is.EqualTo(9));
		}
	}
}
