﻿/*
 * 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 readonly IdGenerator connectionIdGenerator = new IdGenerator();
        private List<Uri> uris;
        private ConnectionInfo 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<SessionInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<SessionInfo>());
        }

        [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<ConsumerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetStartResourceCalls<ConsumerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<ConsumerInfo>());
        }

        [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<ProducerInfo>());
            Assert.AreEqual(1, mockPeer.ContextStats.GetDestroyResourceCalls<ProducerInfo>());
        }

        [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 ConnectionInfo CreateConnectionInfo()
        {
            return new ConnectionInfo(connectionIdGenerator.GenerateId());
        }
    }
}