using System;
using System.Activities;
using System.Activities.Debugger;
using System.Activities.Presentation;
using System.Activities.Presentation.Debug;
using System.Activities.Presentation.Services;
using System.Activities.Statements;
using System.Activities.Tracking;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activities;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Threading.Tasks;
using System.Xaml;
using Microsoft.VisualStudio.TestTools.UnitTesting;


using SignalR.Client;

namespace CheckOutSignalR.Tests
{
    [TestClass]
    public class IntegrationTests
    {
        [TestMethod]
        public void TestMethod1()
        {
            Connection connection = new Connection("http://localhost:40253/registration");
            Task task = connection.Start();
            task.Wait();
            Console.WriteLine(task.Status);
            //    .ContinueWith(task =>
            //{
            //    if (task.IsFaulted)
            //    {
            //        Console.WriteLine("Failed to start: {0}", task.Exception.GetBaseException());
            //    }
            //    else
            //    {
            //        Console.WriteLine("Success! Connected with client connection id {0}", connection.ConnectionId);
            //        // Do more stuff here
            //    }
            //});
            connection.Send("signalr tracking started");
        }

        [TestMethod]
        public void ActivityIDMatchesDesigner()
        {
            const string workflowName = @"c:\users\panmanphil\documents\visual studio 2012\Projects\Scratch\VBRaceEventRegistration\VBRaceEventRegistration.xamlx";
            WorkflowDesigner designer = new WorkflowDesigner();
            IDesignerDebugView  debugger= designer.DebugManagerView;

            designer.Load(workflowName);
            ModelService modelService =designer.Context.Services.GetService<ModelService>();
            
            object rootInstance = modelService.Root.GetCurrentValue();
            IDebuggableWorkflowTree debuggableWorkflowTree = rootInstance as IDebuggableWorkflowTree;
            Activity rootElement = null;
            if (debuggableWorkflowTree != null)
            {
                rootElement = debuggableWorkflowTree.GetWorkflowRoot();
            }

            Assert.IsNotNull(rootElement);
            
            Dictionary<object, SourceLocation> designerSourceLocationMapping = new Dictionary<object, SourceLocation>();
            SourceLocationProvider.CollectMapping(rootElement, rootElement, designerSourceLocationMapping,
                   designer.Context.Items.GetValue<WorkflowFileItem>().LoadedFile);

            object serviceImplementation = XamlServices.Load(workflowName);
            WorkflowService service = serviceImplementation as WorkflowService;
            Activity root = null;
            if (service != null)
                root = service.Body;
            WorkflowInspectionServices.CacheMetadata(root);
            
            IEnumerator<Activity> enumerator1 = WorkflowInspectionServices.GetActivities(root).GetEnumerator();
            Sequence seq = root as Sequence;
            Flowchart chart = root as Flowchart;
            
            List<Activity> ids = new List<Activity>();
            ids.Add(root);
            while (enumerator1.MoveNext())
            {
                ids.Add(enumerator1.Current);
            }
            Assert.AreEqual(designerSourceLocationMapping.Keys.Count, ids.Count);
            int i = 0;
            foreach (Activity act in designerSourceLocationMapping.Keys)
            {
                Assert.AreEqual(act.Id, ids[i].Id);
                i++;
            }
            WorkflowServiceHost app = new WorkflowServiceHost(rootElement) ;
            TestParticipant ppt = new TestParticipant(ids)
                {
                    TrackingProfile =  new TrackingProfile()
                        {
                            Name = "test ppt",
                            
                        }
                };
            ppt.TrackingProfile.Queries.Add(new WorkflowInstanceQuery{ States = { "*" }});
            ppt.TrackingProfile.Queries.Add(new ActivityStateQuery(){States = {"*"}});
            ppt.TrackingProfile.Queries.Add(new BookmarkResumptionQuery() { Name = "*" });
            app.Description.Behaviors.Add(ppt);
            app.Open();
            
        
        }
    }
    class TestParticipant : TrackingParticipant, IServiceBehavior
    {
        private IList<Activity> _designActivities;
        public TestParticipant(IList<Activity> designActivities )
        {
            _designActivities = designActivities;
        }
        protected override void Track(TrackingRecord record, TimeSpan timeout)
        {
            ActivityStateRecord stateRecord = record as ActivityStateRecord;
            WorkflowInstanceRecord wfInstanceRecord = record as WorkflowInstanceRecord;
            if (stateRecord != null)
            {
                var sequences = _designActivities.Where(q => q.Id == stateRecord.Activity.Id );
                Assert.AreEqual(1, sequences.Count());
            }
            if (wfInstanceRecord != null)
            {
                //var workflows = _designActivities.Where(q => q.Id == wfInstanceRecord.InstanceId);
            }
        }

       

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            WorkflowServiceHost serviceHost = serviceHostBase as WorkflowServiceHost;
            
            serviceHost.WorkflowExtensions.Add(this);
        }
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {

        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {

        }
    }
}
