using System.Net;
using Microsoft.Extensions.DependencyInjection;
using Persistence.Client;
using Persistence.Client.Clients;
using Xunit;

namespace Persistence.IntegrationTests.Controllers
{
	public class SetpointControllerTest : BaseIntegrationTest
	{
		private ISetpointClient setpointClient;
		private class TestObject
		{
			public string? value1 { get; set; }
			public int? value2 { get; set; }
		}
		public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory) 
		{
			var scope = factory.Services.CreateScope();
			var persistenceClientFactory = scope.ServiceProvider
				.GetRequiredService<PersistenceClientFactory>();

			setpointClient = persistenceClientFactory.GetClient<ISetpointClient>();
		}

		[Fact]
		public async Task GetCurrent_returns_success()
		{
			//arrange
			var setpointKeys = new List<Guid>()
			{
				Guid.NewGuid(),
				Guid.NewGuid()
			};

			//act
			var response = await setpointClient.GetCurrent(setpointKeys);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.Empty(response.Content);
		}

		[Fact]
		public async Task GetCurrent_AfterSave_returns_success()
		{
			//arrange
			var setpointKey = await Save();

			//act
			var response = await setpointClient.GetCurrent([setpointKey]);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.NotEmpty(response.Content);
			Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
		}

		[Fact]
		public async Task GetHistory_returns_success()
		{
			//arrange
			var setpointKeys = new List<Guid>()
			{
				Guid.NewGuid(),
				Guid.NewGuid()
			};
			var historyMoment = DateTimeOffset.UtcNow;

			//act
			var response = await setpointClient.GetHistory(setpointKeys, historyMoment);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.Empty(response.Content);
		}

		[Fact]
		public async Task GetHistory_AfterSave_returns_success()
		{
			//arrange
			var setpointKey = await Save();
			var historyMoment = DateTimeOffset.UtcNow;
			historyMoment = historyMoment.AddDays(1);

			//act
			var response = await setpointClient.GetHistory([setpointKey], historyMoment);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.NotEmpty(response.Content);
			Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key);
		}

		[Fact]
		public async Task GetLog_returns_success()
		{
			//arrange
			var setpointKeys = new List<Guid>()
			{
				Guid.NewGuid(),
				Guid.NewGuid()
			};

			//act
			var response = await setpointClient.GetLog(setpointKeys);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.Empty(response.Content);
		}

		[Fact]
		public async Task GetLog_AfterSave_returns_success()
		{
			//arrange
			var setpointKey = await Save();

			//act
			var response = await setpointClient.GetLog([setpointKey]);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);
			Assert.NotNull(response.Content);
			Assert.NotEmpty(response.Content);
			Assert.Equal(setpointKey, response.Content.FirstOrDefault().Key);
		}

		[Fact]
		public async Task Save_returns_success()
		{
			await Save();
		}

		private async Task<Guid> Save()
		{
			//arrange
			var setpointKey = Guid.NewGuid();
			var setpointValue = new TestObject()
			{
				value1 = "1",
				value2 = 2
			};

			//act
			var response = await setpointClient.Save(setpointKey, setpointValue);

			//assert
			Assert.Equal(HttpStatusCode.OK, response.StatusCode);

			return setpointKey;
		}
	}
}