public void TestChatComparerWithLastMessage()
        {
            var highestVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 1000000
            });
            var lastMessageLowVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 1, LastMessage = new Message()
                {
                    version = "1"
                }
            });
            var lastMessageHighVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 1, LastMessage = new Message()
                {
                    version = "10"
                }
            });

            // last message version always wins
            Assert.AreEqual(-1, highestVersion.CompareTo(lastMessageLowVersion));
            Assert.AreEqual(1, lastMessageLowVersion.CompareTo(highestVersion));

            // compare last message versions
            Assert.AreEqual(-1, lastMessageLowVersion.CompareTo(lastMessageHighVersion));
            Assert.AreEqual(1, lastMessageHighVersion.CompareTo(lastMessageLowVersion));
            Assert.AreEqual(0, lastMessageLowVersion.CompareTo(lastMessageLowVersion));
        }
        public void TestQueueOperations()
        {
            var chatsToRetrieve = new SimplePriorityQueue <ChatQueueItem, HigherVersionWinsComparerChat>(new LowerVersionWinsChatComparer());

            var dummyContext = new TeamsDataContext((TeamsParticipant)"00000000-0000-beef-0000-000000000000", new ProcessedTenant(new Tenant(), DateTime.UtcNow));

            var chatLowVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 5, id = "1"
            });
            var chatMediumVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 50, id = "2"
            });
            var chatHighVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 500, id = "3"
            });

            chatsToRetrieve.Enqueue(new ChatQueueItem(dummyContext, chatLowVersion), chatLowVersion);
            chatsToRetrieve.Enqueue(new ChatQueueItem(dummyContext, chatMediumVersion), chatMediumVersion);
            chatsToRetrieve.Enqueue(new ChatQueueItem(dummyContext, chatHighVersion), chatHighVersion);

            var isRemoved = chatsToRetrieve.TryRemove(new ChatQueueItem(dummyContext, chatMediumVersion));

            Assert.IsTrue(isRemoved);
            isRemoved = chatsToRetrieve.TryRemove(new ChatQueueItem(dummyContext, chatMediumVersion));
            Assert.IsFalse(isRemoved);
        }
        public void TestChatPriorityQueue()
        {
            var chatsToRetrieve = new SimplePriorityQueue <(TeamsDataContext, HigherVersionWinsComparerChat), HigherVersionWinsComparerChat>(new LowerVersionWinsChatComparer());

            var dummyContext   = new TeamsDataContext();
            var chatLowVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 5
            });
            var chatMediumVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 50
            });
            var chatHighVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 500
            });

            // note: last message version _always_ comes before any "normal" thread version
            var chatWithLowestLastMessageVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 5000, LastMessage = new Message()
                {
                    version = "1"
                }
            });
            var chatWithHighestLastMessageVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 1, LastMessage = new Message()
                {
                    version = "50000"
                }
            });

            chatsToRetrieve.Enqueue((dummyContext, chatLowVersion), chatLowVersion);
            chatsToRetrieve.Enqueue((dummyContext, chatHighVersion), chatHighVersion);
            chatsToRetrieve.Enqueue((dummyContext, chatMediumVersion), chatMediumVersion);
            chatsToRetrieve.Enqueue((dummyContext, chatWithLowestLastMessageVersion), chatWithLowestLastMessageVersion);
            chatsToRetrieve.Enqueue((dummyContext, chatWithHighestLastMessageVersion), chatWithHighestLastMessageVersion);

            (TeamsDataContext, HigherVersionWinsComparerChat)chat;

            chat = chatsToRetrieve.Dequeue();
            Assert.AreEqual(1, chat.Item2.Chat.version);
            chat = chatsToRetrieve.Dequeue();
            Assert.AreEqual(5000, chat.Item2.Chat.version);
            chat = chatsToRetrieve.Dequeue();
            Assert.AreEqual(500, chat.Item2.Chat.version);
            chat = chatsToRetrieve.Dequeue();
            Assert.AreEqual(50, chat.Item2.Chat.version);
            chat = chatsToRetrieve.Dequeue();
            Assert.AreEqual(5, chat.Item2.Chat.version);
        }
        public void TestChatComparerWithNulls()
        {
            var nullChat = new HigherVersionWinsComparerChat(null);
            var chat     = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 10
            });

            // last message version always wins
            Assert.AreEqual(-1, nullChat.CompareTo(chat));
            Assert.AreEqual(1, chat.CompareTo(nullChat));
            Assert.AreEqual(0, nullChat.CompareTo(nullChat));
        }
        public void TestChatComparerSimple()
        {
            var lowVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 1
            });
            var highVersion = new HigherVersionWinsComparerChat(new Chat()
            {
                version = 10
            });

            Assert.AreEqual(-1, lowVersion.CompareTo(highVersion));
            Assert.AreEqual(1, highVersion.CompareTo(lowVersion));
            Assert.AreEqual(0, lowVersion.CompareTo(lowVersion));
            Assert.AreEqual(1, lowVersion.CompareTo(null));
        }
        private async Task RetrieveChatsAsync(TeamsDataContext ctx)
        {
            logger.Debug("[{TenantName}] Entering {Method} for tenant | {Context}", ctx.Tenant.TenantName, nameof(RetrieveChatsAsync), ctx);

            var debugWhiteList = new List <string>();

            if (debugWhiteList.Count == 0)
            {
                EnsureLongPollingEndpointsAreUpAndRunning(ctx);
            }

            MyChatsAndTeams?myChatsAndTeams = await chatRegistry.GetUpdatedChatsAndTeamsAsync(ctx);

            if (myChatsAndTeams == null)
            {
                logger.Debug("[{TenantName}] Got no chats in {Method}, exiting", ctx.Tenant.TenantName, nameof(RetrieveChatsAsync));
                return;
            }

            logger.Debug("[{TenantName}] Retrieved {ChatCount} chats, queuing all for retrieval/update check | {Context}", ctx.Tenant.TenantName, myChatsAndTeams.chats.Count, ctx);
            var queue = GetQueueForDataContext(ctx);

            foreach (var chat in myChatsAndTeams.chats)
            {
                var comparableChat = new HigherVersionWinsComparerChat(chat);
                if (queue.TryRemove(new ChatQueueItem(ctx, comparableChat)))
                {
                    logger.Verbose("[{TenantName}] Updating already queued chat {ChatId} retrieval entry | {Context}", ctx.Tenant.TenantName, chat.id.Truncate(Constants.ChatIdLogLength, true), ctx);
                }

                if (debugWhiteList.Count == 0 || debugWhiteList.Contains(chat.id))
                {
                    queue.Enqueue(new ChatQueueItem(ctx, comparableChat), comparableChat);
                }
            }
        }