using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Moq.Protected;
using HttpClientWrapper;

namespace YourNamespaceHere
{
	public class FakeHttpMessageHandler : HttpMessageHandler
	{
		public virtual HttpResponseMessage Send(HttpRequestMessage request)
		{
			throw new NotImplementedException("Now we can setup this method with our mocking framework");
		}

		protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
		{
			return Task.FromResult(Send(request));
		}

		public static Mock<HttpMessageHandler> GetMockHandler(HttpResponseMessage response)
		{
			var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
			handlerMock
				.Protected()
				// Setup the PROTECTED method to mock
				.Setup<Task<HttpResponseMessage>>(
					"SendAsync",
					ItExpr.IsAny<HttpRequestMessage>(),
					ItExpr.IsAny<CancellationToken>()
				)
				// prepare the expected response of the mocked http call
				.ReturnsAsync(response)
				.Verifiable();

			return handlerMock;
		}

		public static void SetMockHandler(HttpClientWrapper proxy, string jsonResponse)
		{
			var h = new HttpResponseMessage()
			{
				StatusCode = HttpStatusCode.OK,
				Content = new StringContent(jsonResponse)
			};

			//	Please see FakeHttpMessageHandler.cs for more information
			var handlerMock = GetMockHandler(h);

			proxy.SendAsyncMessageHandler = handlerMock.Object;
		}
	}
}