// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

namespace Microsoft.Samples.WindowsAzureMmc.Powershell.Host.Tests.Storage
{
    using System;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using Microsoft.Samples.WindowsAzureMmc.Model.Storage;
    using Microsoft.Samples.WindowsAzureMmc.Powershell.Host;
    using Microsoft.Samples.WindowsAzureMmc.Powershell.Host.Tests.Helpers;
    using Microsoft.Samples.WindowsAzureMmc.Powershell.Host.Tests.Properties;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class Queues
    {
        private const string GOODQUEUENAME = "qtestq";
        private const string NOTEXISTSQUEUENAME = "fredisadog";
        private const string BADQUEUENAME = "&$^*&$^^$&*($^&*(";
        private const int MAXMESSAGES = 32;

        private static AzurePSHost host;

        [ClassInitialize()]
        public static void QueuesInitialize(TestContext context)
        {
            host = new AzurePSHost(Settings.Default.Account, Settings.Default.Key, true, new Uri(Settings.Default.BlobServiceUrl), new Uri(Settings.Default.QueueServiceUrl), new PSHostUIForTesting());
        }

        [ClassCleanup()]
        public static void QueuesCleanup()
        {
            ((IDisposable)host).Dispose();
        }

        [TestCleanup]
        public void TestCleanup()
        {
            try
            {
                host.DeleteQueue(GOODQUEUENAME);
            }
            catch 
            { 
            }
        }

        [TestMethod]
        public void CreateQueue()
        {
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");
            Assert.AreEqual<string>(GOODQUEUENAME, queue.Name);
            Assert.AreEqual<int>(0, queue.Length);
        }

        [TestMethod]
        public void GetQueueList()
        {
            // get a list of queues
            Collection<AzureQueue> queues = host.RetrieveQueues();
            Assert.IsNotNull(queues, "Could not get any queues");

            int count = queues.Count;

            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // get a list of queues - there should be one more than we started with
            queues = host.RetrieveQueues();
            Assert.IsNotNull(queues, "Could not get any queues");
            Assert.IsTrue(queues.Count == count + 1, "Could not get the correct number of queues");
        }

        [TestMethod]
        public void GetQueue()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            queue = host.RetrieveQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Queue could not be found");
        }

        [TestMethod]
        public void DeleteQueue()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // delete it
            host.DeleteQueue(GOODQUEUENAME);

            // see if it's still there
            queue = host.RetrieveQueue(GOODQUEUENAME);
            Assert.IsNull(queue, "Queue was found after deletion");
        }

        [TestMethod]
        public void Peek10Messages()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // add some messages
            host.CreateMessage(GOODQUEUENAME, "testone");
            host.CreateMessage(GOODQUEUENAME, "testtwo");
            host.CreateMessage(GOODQUEUENAME, "testthree");

            // peek the messages
            Collection<AzureMessage> messages = host.PeekMessages(GOODQUEUENAME, 10, true);
            Assert.IsNotNull(messages, "Failed to Peek Messages");
            Assert.IsTrue(messages.Count == 3, "Did not find exactly 3 messages in the queue");
        }

        [TestMethod]
        public void PeekMaxMessages()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // add MAX messages plus a couple more
            for (int i = 0; i < MAXMESSAGES + 2; i++)
            {
                host.CreateMessage(GOODQUEUENAME, "test" + i.ToString(CultureInfo.InvariantCulture));
            }

            // peek the messages
            Collection<AzureMessage> messages = host.PeekMessages(GOODQUEUENAME, MAXMESSAGES, true);
            Assert.IsNotNull(messages, "Failed to Peek Messages");
            Assert.IsTrue(messages.Count == MAXMESSAGES, "Did not find exactly MAX messages in the queue");
        }

        [TestMethod]
        public void PeekAllMessagesOnEmptyQueue()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // peek the messages
            Collection<AzureMessage> messages = host.PeekMessages(GOODQUEUENAME, MAXMESSAGES, true);
            Assert.IsNotNull(messages, "Failed to Peek Messages");
            Assert.IsTrue(messages.Count == 0, "Messages found in the queue when there should be none");
        }

        [TestMethod]
        public void PurgeMessages()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // add some messages
            host.CreateMessage(GOODQUEUENAME, "testone");
            host.CreateMessage(GOODQUEUENAME, "testtwo");
            host.CreateMessage(GOODQUEUENAME, "testthree");

            // peek the messages and make sure there are 3
            Collection<AzureMessage> messages = host.PeekMessages(GOODQUEUENAME, MAXMESSAGES, true);
            Assert.IsNotNull(messages, "Failed to Peek Messages");
            Assert.IsTrue(messages.Count == 3, "Did not find exactly 3 messages in the queue");

            // purge the queue
            host.PurgeQueue(GOODQUEUENAME);

            // see if there are any messages left in the queue
            messages = host.PeekMessages(GOODQUEUENAME, MAXMESSAGES, true);
            Assert.IsNotNull(messages, "Failed to Peek Messages");
            Assert.IsTrue(messages.Count == 0, "Messages in the queue after purge");
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.CmdletProviderInvocationException))]
        public void CreateQueueWithBadName()
        {
            AzureQueue queue = host.CreateQueue(BADQUEUENAME);
            Assert.IsNull(queue, "Queue was created with a bad name");
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.ActionPreferenceStopException))]
        public void CreateQueueWithBlankName()
        {
            AzureQueue queue = host.CreateQueue(string.Empty);
            Assert.IsNull(queue, "Queue was created with an empty name");
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.CmdletProviderInvocationException))]
        public void CreateQueueWithReallyLongName()
        {
            string reallyLongName = "abcdefghijklmnopqrstuvwxyz";
            for (int i = 0; i < 5; i++)
            {
                reallyLongName += reallyLongName;
            }

            AzureQueue queue = host.CreateQueue(reallyLongName);
            Assert.IsNull(queue, "Queue was created with a really long name");
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.ActionPreferenceStopException))]
        public void DeleteNotExistsQueue()
        {
            host.DeleteQueue(NOTEXISTSQUEUENAME);
        }

        [TestMethod]
        public void PeekMessagesFromNotExistsQueue()
        {
            Collection<AzureMessage> messages = host.PeekMessages(NOTEXISTSQUEUENAME, 10, false);
            Assert.IsNotNull(messages, "Messages collection should be empty but not null");
            Assert.IsTrue(messages.Count == 0, "Messages found in non-existant queue, which is really wierd");
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.MethodInvocationException))]
        public void PeekTooManyMessagesFromQueue()
        {
            // make a queue
            AzureQueue queue = host.CreateQueue(GOODQUEUENAME);
            Assert.IsNotNull(queue, "Failed to create queue");

            // add some messages
            host.CreateMessage(GOODQUEUENAME, "testone");
            host.CreateMessage(GOODQUEUENAME, "testtwo");
            host.CreateMessage(GOODQUEUENAME, "testthree");

            // peek the messages and make sure there are 3
            Collection<AzureMessage> messages = host.PeekMessages(GOODQUEUENAME, MAXMESSAGES + 10, true);

            Assert.IsNotNull(messages);
            Assert.AreEqual<int>(3, messages.Count);
        }

        [TestMethod]
        [ExpectedException(typeof(System.Management.Automation.ActionPreferenceStopException))]
        public void PurgeMessagesFromNotExistsQueue()
        {
            host.PurgeQueue(NOTEXISTSQUEUENAME);
        }
    }
}