﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Apache.NMS;
using Apache.NMS.AMQP;
using Apache.NMS.AMQP.Meta;
using Apache.NMS.AMQP.Provider;
using Apache.NMS.AMQP.Provider.Failover;
using Apache.NMS.AMQP.Util;
using Moq;
using NMS.AMQP.Test.Provider.Mock;
using NUnit.Framework;

namespace NMS.AMQP.Test.Provider
{
    /// <summary>
    /// Test behavior of the FailoverProvider
    /// </summary>
    [TestFixture]
    public class FailoverProviderTest
    {
        private List<Uri> uris;
        private NmsConnectionInfo connectionInfo;
        private FailoverProvider provider;
        private MockRemotePeer mockPeer;

        [SetUp]
        public void SetUp()
        {
            uris = new List<Uri>
            {
                new Uri("mock://192.168.2.1:5672"),
                new Uri("mock://192.168.2.2:5672"),
                new Uri("mock://192.168.2.3:5672"),
                new Uri("mock://192.168.2.4:5672"),
            };
            connectionInfo = CreateConnectionInfo();
            mockPeer = new MockRemotePeer();
            mockPeer.Start();
            ProviderFactory.RegisterProviderFactory("mock", new MockProviderFactory());
        }

        [TearDown]
        public void TearDown()
        {
            if (provider != null)
            {
                provider.Close();
                provider = null;
            }

            if (mockPeer != null)
            {
                mockPeer.Terminate();
                mockPeer = null;
            }
        }

        [Test]
        public void TestCreateProviderOnlyUris()
        {
            provider = new FailoverProvider(uris);
            Assert.IsNull(provider.RemoteUri);
        }

        [Test, Timeout(3000)]
        public async Task TestGetRemoteUri()
        {
            provider = new FailoverProvider(uris);
            provider.SetProviderListener(new Mock<IProviderListener>().Object);
            Assert.IsNull(provider.RemoteUri);
            await provider.Connect(connectionInfo);
            Assert.IsNotNull(provider.RemoteUri);
        }

        [Test, Timeout(3000)]
        public async Task TestToString()
        {
            provider = new FailoverProvider(uris);
            provider.SetProviderListener(new Mock<IProviderListener>().Object);
            Assert.IsNotNull(provider.ToString());
            await provider.Connect(connectionInfo);
            Assert.True(provider.ToString().Contains("mock://"));
        }

        [Test, Timeout(3000)]
        public async Task TestConnectToMock()
        {
            provider = new FailoverProvider(uris);
            provider.SetProviderListener(new Mock<IProviderListener>().Object);
            await provider.Connect(connectionInfo);
            provider.Close();
            Assert.That(mockPeer.ContextStats.ProvidersCreated, Is.EqualTo(1));
            Assert.That(mockPeer.ContextStats.ConnectionAttempts, Is.EqualTo(1));
        }

        [Test, Timeout(3000)]
        public void TestCannotStartWithoutListener()
        {
            provider = new FailoverProvider(uris);
            Assert.Throws<IllegalStateException>(() => provider.Start());
        }

        [Test, Timeout(3000)]
        public void TestStartupMaxReconnectAttempts()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost:5000?mock.failOnConnect=true)" +
                "?failover.startupMaxReconnectAttempts=5" +
                "&failover.useReconnectBackOff=false");
            IConnection connection = null;
            try
            {
                connection = factory.CreateConnection();
                connection.Start();
                Assert.Fail("Should have stopped after five retries.");
            }
            catch (NMSException)
            {
            }
            finally
            {
                connection?.Close();
            }

            Assert.AreEqual(5, mockPeer.ContextStats.ProvidersCreated);
            Assert.AreEqual(5, mockPeer.ContextStats.ConnectionAttempts);
            Assert.AreEqual(5, mockPeer.ContextStats.CloseAttempts);
        }

        [Test, Timeout(3000)]
        public void TestMaxReconnectAttemptsWithMultipleUris()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://192.168.2.1?mock.failOnConnect=true," +
                "mock://192.168.2.2?mock.failOnConnect=true," +
                "mock://192.168.2.3?mock.failOnConnect=true)" +
                "?failover.maxReconnectAttempts=5" +
                "&failover.reconnectDelay=1" +
                "&failover.useReconnectBackOff=false");

            IConnection connection = null;
            try
            {
                connection = factory.CreateConnection();
                connection.Start();
                Assert.Fail("Should have stopped after five retries.");
            }
            catch (NMSException)
            {
            }
            finally
            {
                connection?.Close();
            }

            Assert.AreEqual(15, mockPeer.ContextStats.ProvidersCreated);
            Assert.AreEqual(15, mockPeer.ContextStats.ConnectionAttempts);
            Assert.AreEqual(15, mockPeer.ContextStats.CloseAttempts);
        }

        [Test, Timeout(3000)]
        public void TestMaxReconnectAttemptsWithBackOff()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost?mock.failOnConnect=true)" +
                "?failover.maxReconnectAttempts=5" +
                "&failover.maxReconnectDelay=60" +
                "&failover.reconnectDelay=10" +
                "&failover.useReconnectBackOff=true");

            IConnection connection = null;
            try
            {
                connection = factory.CreateConnection();
                connection.Start();
                Assert.Fail("Should have stopped after five retries.");
            }
            catch (NMSException)
            {
            }
            finally
            {
                connection?.Close();
            }

            Assert.AreEqual(5, mockPeer.ContextStats.ProvidersCreated);
            Assert.AreEqual(5, mockPeer.ContextStats.ConnectionAttempts);
            Assert.AreEqual(5, mockPeer.ContextStats.CloseAttempts);
        }

        [Test]
        public void TestFailureOnCloseIsSwallowed()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost?mock.failOnClose=true)");

            IConnection connection = factory.CreateConnection();
            connection.Start();
            connection.Close();

            Assert.AreEqual(1, mockPeer.ContextStats.ProvidersCreated);
            Assert.AreEqual(1, mockPeer.ContextStats.ConnectionAttempts);
            Assert.AreEqual(1, mockPeer.ContextStats.CloseAttempts);
        }

        [Test, Timeout(3000)]
        public void TestSessionLifeCyclePassthrough()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
            "failover:(mock://localhost)");

            IConnection connection = factory.CreateConnection();
            connection.Start();
            connection.CreateSession(AcknowledgementMode.AutoAcknowledge).Close();
            connection.Close();

            Assert.AreEqual(1, mockPeer.ContextStats.GetCreateResourceCalls<NmsSessionInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<NmsSessionInfo>());
        }

        [Test, Timeout(3000)]
        public void TestConsumerLifeCyclePassthrough()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost)");

            IConnection connection = factory.CreateConnection();
            connection.Start();
            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
            var topic = session.GetTopic("test");
            session.CreateConsumer(topic).Close();
            connection.Close();

            Assert.AreEqual(1, mockPeer.ContextStats.GetCreateResourceCalls<NmsConsumerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetStartResourceCalls<NmsConsumerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<NmsConsumerInfo>());
        }

        [Test, Timeout(300000)]
        public void TestProducerLifeCyclePassthrough()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost)");

            IConnection connection = factory.CreateConnection();
            connection.Start();
            ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
            var topic = session.GetTopic("test");
            session.CreateProducer(topic).Close();
            connection.Close();

            Assert.AreEqual(1, mockPeer.ContextStats.GetCreateResourceCalls<NmsProducerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<NmsProducerInfo>());
        }

        [Test, Timeout(300000)]
        public void TestSessionRecoverPassthrough()
        {
            NmsConnectionFactory factory = new NmsConnectionFactory(
                "failover:(mock://localhost)");

            IConnection connection = factory.CreateConnection();
            connection.Start();
            ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge);
            session.Recover();
            connection.Close();

            Assert.AreEqual(1, mockPeer.ContextStats.RecoverCalls);
        }

        private NmsConnectionInfo CreateConnectionInfo()
        {
            return new NmsConnectionInfo(new NmsConnectionId("test"));
        }
    }
}