using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using IndianHealthService.BMXNet.Ado;
using System.Threading;

namespace IndianHealthService.BMXNet.Tests.AdoTests
{
    [TestFixture]
    public class AsyncAdoTests : BmxValidUserTestSuite
    {

        public override void SetupTestUser()
        {
            this.User = TestUser.ReadFromAppConfig("BmxTestUser");
        }

        public override void Setup()
        {
            this.TheFuture = null;
            base.Setup();
        }

        private DataTableFuture _theFuture = null;

        public DataTableFuture TheFuture
        {
            get { return _theFuture; }
            set { _theFuture = value; }
        }



        [Test]
        public void BadStandardAsyncFetch()
        {
            int timeToWait = 3;
            this.RemoteSession.EventServices.EventPollingInterval = 2000;
            this.RemoteSession.EventServices.IsEventPollingEnabled = true;
            Thread.Sleep(timeToWait * 1000);
            TestTable testTable = TestTable.TypicalTableFetch();
            try
            {
                DataTableFuture futureTestStandardAsyncFetch = this.RemoteSession.AsyncTableFromCommand("DOES NOT EXIST");
            } catch {
            
            }
        }

        [Test]
        public void StandardAsyncFetch()
        {
            int timeToWait = 3;
            this.RemoteSession.EventServices.EventPollingInterval = 2000;
            this.RemoteSession.EventServices.IsEventPollingEnabled = true;

            TestTable testTable = TestTable.TypicalTableFetch();
            this.RemoteSession.AppContext = "BMXRPC";
            DataTableFuture futureTestStandardAsyncFetch = this.RemoteSession.AsyncTableFromCommand(testTable.AsyncCommand("Test1", timeToWait));
            futureTestStandardAsyncFetch.Returned += new EventHandler<DataTableFutureEventArgs>(futureTestStandardAsyncFetch_Returned);

            Assert.IsNull(this.TheFuture);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsFalse(futureTestStandardAsyncFetch.WasCancelled);
            this.Hang(5);
            Assert.IsNull(this.TheFuture);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsFalse(futureTestStandardAsyncFetch.WasCancelled);            
            this.Hang((int)((timeToWait + 1) * 2));
            Assert.IsNotNull(this.TheFuture);
            Assert.IsTrue(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsTrue(futureTestStandardAsyncFetch.HasData);
            Assert.IsFalse(futureTestStandardAsyncFetch.WasCancelled);
            Assert.AreEqual(testTable.Repeat, futureTestStandardAsyncFetch.Result.Rows.Count);
        }

        void futureTestStandardAsyncFetch_Returned(object sender, DataTableFutureEventArgs e)
        {
            this.TheFuture = e.Future;
        }

    public void NonExistantRpcAsyncFetch()
        {
            int timeToWait = 3;
            this.RemoteSession.EventServices.EventPollingInterval = 1000;
            this.RemoteSession.EventServices.IsEventPollingEnabled = true;

            DataTableFuture futureTestStandardAsyncFetch = this.RemoteSession.AsyncTableFromCommand("NON EXISTANT RPC");
            futureTestStandardAsyncFetch.Returned += new EventHandler<DataTableFutureEventArgs>(futureTestStandardAsyncFetch_Returned);
            this.Hang(5 + timeToWait);
            //We should get a fast response
            Assert.IsNotNull(this.TheFuture);
            Assert.IsTrue(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasData);
        }


         public void CancelAsyncFetch()
        {
            int timeToWait = 10;
            this.RemoteSession.EventServices.EventPollingInterval = 2000;
            this.RemoteSession.EventServices.IsEventPollingEnabled = true;

            TestTable testTable = TestTable.TypicalTableFetch();
            DataTableFuture futureTestStandardAsyncFetch = this.RemoteSession.AsyncTableFromCommand(testTable.AsyncCommand("Test1", timeToWait));
            futureTestStandardAsyncFetch.Returned += new EventHandler<DataTableFutureEventArgs>(futureTestStandardAsyncFetch_Returned);

            Assert.IsNull(this.TheFuture);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsFalse(futureTestStandardAsyncFetch.WasCancelled);
            this.Hang(5);
            futureTestStandardAsyncFetch.Cancel();
            Assert.IsNull(this.TheFuture);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsTrue(futureTestStandardAsyncFetch.WasCancelled);
            this.Hang(20);
            Assert.IsNotNull(this.TheFuture);
            Assert.IsTrue(futureTestStandardAsyncFetch.HasReturned);
            Assert.IsFalse(futureTestStandardAsyncFetch.HasData);
            Assert.IsTrue(futureTestStandardAsyncFetch.WasCancelled);
         }
      
    }
}
