﻿/**
 * 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
 *
 *     https://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;
using Avro.ipc;
using Avro.ipc.Specific;
using NUnit.Framework;
using org.apache.avro.test;

namespace Avro.Test.Ipc
{
    [TestFixture]
    public class SocketTransceiverWhenServerStopsTest
    {
        private static org.apache.avro.test.Message CreateMessage()
        {
            var msg = new org.apache.avro.test.Message
                          {
                              to = "wife",
                              from = "husband",
                              body = "I love you!"
                          };
            return msg;
        }

        private static readonly DateTime Jan1st1970 = new DateTime
            (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        public static long CurrentTimeMillis()
        {
            return (long) (DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
        }

        public class MailImpl : Mail
        {
            private CountdownLatch allMessages = new CountdownLatch(5);

            // in this simple example just return details of the message
            public override String send(org.apache.avro.test.Message message)
            {
                return "Sent message to [" + message.to +
                       "] from [" + message.from + "] with body [" +
                       message.body + "]";
            }

            public override void fireandforget(org.apache.avro.test.Message message)
            {
                allMessages.Signal();
            }

            public void reset()
            {
                allMessages = new CountdownLatch(5);
            }
        }

        [Test]
        public void TestSocketTransceiverWhenServerStops()
        {
            Responder responder = new SpecificResponder<Mail>(new MailImpl());
            var server = new SocketServer("localhost", 0, responder);

            server.Start();

            var transceiver = new SocketTransceiver("localhost", server.Port);
            var mail = SpecificRequestor.CreateClient<Mail>(transceiver);

            int[] successes = {0};
            int failures = 0;
            int[] quitOnFailure = {0};
            var threads = new List<Thread>();

            // Start a bunch of client threads that use the transceiver to send messages
            for (int i = 0; i < 100; i++)
            {
                var thread = new Thread(
                    () =>
                        {
                            while (true)
                            {
                                try
                                {
                                    mail.send(CreateMessage());
                                    Interlocked.Increment(ref successes[0]);
                                }
                                catch (Exception)
                                {
                                    Interlocked.Increment(ref failures);

                                    if (Interlocked.Add(ref quitOnFailure[0], 0) == 1)
                                    {
                                        return;
                                    }
                                }
                            }
                        });

                thread.Name = "Thread" + i;
                threads.Add(thread);
                thread.Start();
            }

            // Be sure the threads are running: wait until we get a good deal of successes
            while (Interlocked.Add(ref successes[0], 0) < 10000)
            {
                Thread.Sleep(50);
            }

            // Now stop the server
            server.Stop();

            // Server is stopped: successes should not increase anymore: wait until we're in that situation
            while (true)
            {
                int previousSuccesses = Interlocked.Add(ref successes[0], 0);
                Thread.Sleep(500);
                if (previousSuccesses == Interlocked.Add(ref successes[0], 0))
                {
                    break;
                }
            }

            server.Start();

            long now = CurrentTimeMillis();

            int previousSuccesses2 = successes[0];
            while (true)
            {
                Thread.Sleep(500);
                if (successes[0] > previousSuccesses2)
                {
                    break;
                }
                if (CurrentTimeMillis() - now > 5000)
                {
                    Console.WriteLine("FYI: requests don't continue immediately...");
                    break;
                }
            }

            // Stop our client, we would expect this to go on immediately
            Console.WriteLine("Stopping transceiver");

            Interlocked.Add(ref quitOnFailure[0], 1);
            now = CurrentTimeMillis();
            transceiver.Close();

            // Wait for all threads to quit
            while (true)
            {
                threads.RemoveAll(x => !x.IsAlive);

                if (threads.Count > 0)
                    Thread.Sleep(1000);
                else
                    break;
            }

            if (CurrentTimeMillis() - now > 10000)
            {
                Assert.Fail("Stopping NettyTransceiver and waiting for client threads to quit took too long.");
            }
            else
            {
                Console.WriteLine("Stopping NettyTransceiver and waiting for client threads to quit took "
                                  + (CurrentTimeMillis() - now) + " ms");
            }
        }
    }
}