/// <summary>
 /// Test executue a behavior
 /// </summary>
 /// <param name="b"></param>
 /// <param name="completionReport"></param>
 public bool TestExecute(Behavior b, out CompletionReport completionReport)
 {
     if (this.operationalTestFacade != null)
     {
         try
         {
             b.TimeStamp      = CoreCommon.Communications.GetVehicleState().Timestamp;
             completionReport = this.operationalTestFacade.TestExecuteBehavior(b);
             ArbiterOutput.OutputNoLog("test execute: " + b.ShortBehaviorInformation() + " completion report: " + completionReport.GetType().ToString());
             return(completionReport.Result == CompletionResult.Success);
         }
         catch (Exception e)
         {
             completionReport = new SuccessCompletionReport(b.GetType());
             ArbiterOutput.OutputNoLog("test execute: " + b.ShortBehaviorInformation() + " encountered error: " + e.ToString());
             this.TryOperationalTestFacadeConnect();
             return(true);
         }
     }
     else
     {
         completionReport = new SuccessCompletionReport(b.GetType());
         ArbiterOutput.OutputNoLog("test execute: " + b.ShortBehaviorInformation() + " encountered error: operational test facade does not exist");
         this.TryOperationalTestFacadeConnect();
         return(true);
     }
 }
        /// <summary>
        /// Operational competes a behavior
        /// </summary>
        /// <param name="report"></param>
        public override void OnCompletionReport(CompletionReport report)
        {
            try
            {
                if (report.Result == CompletionResult.Success)
                {
                    ArbiterOutput.OutputNoLog("Received Completion Report: " + report.BehaviorType.ToString() + ", Result: " + report.Result.ToString());
                }
                else if (this.ArbiterBlockageHandler != null && report is TrajectoryBlockedReport)
                {
                    this.ArbiterBlockageHandler.OnBlockageReport((TrajectoryBlockedReport)report);
                }

                lock (this.recentReports)
                {
                    this.recentReports = new List <KeyValuePair <CompletionReport, DateTime> >(this.recentReports.ToArray());
                    this.recentReports.Add(new KeyValuePair <CompletionReport, DateTime>(report, DateTime.Now));
                }
            }
            catch (Exception e)
            {
                try
                {
                    ArbiterOutput.OutputNoLog("Error in completion report");
                    ArbiterOutput.WriteToLog(e.ToString());
                }
                catch (Exception)
                {
                }
            }
        }
        /// <summary>
        /// Try to connect to the operational facade
        /// </summary>
        public void TryOperationalTestFacadeConnect()
        {
            if (global::UrbanChallenge.Arbiter.Core.ArbiterSettings.Default.UseTestOperational)
            {
                try
                {
                    // check if test facade ok
                    bool testFacadeGood = this.operationalTestFacade != null;
                    if (this.operationalTestFacade != null)
                    {
                        try
                        {
                            this.operationalTestFacade.Ping();
                            this.testComponentExists = true;
                        }
                        catch (Exception)
                        {
                            testFacadeGood = false;
                        }
                    }

                    // set the operational test facade if not ok
                    if (!testFacadeGood)
                    {
                        // get the operational layer
                        this.operationalTestFacade = (OperationalTestComponentFacade)objectDirectory.Resolve("OperationalTestComponentService" + this.RemotingSuffix);
                        this.testComponentExists   = true;
                    }

                    // try to send road network
                    if (CoreCommon.RoadNetwork != null)
                    {
                        this.operationalTestFacade.SetRoadNetwork(CoreCommon.RoadNetwork);
                        this.testComponentNeedsRoadNetwork = false;
                    }
                }
                catch (Exception ex)
                {
                    ArbiterOutput.OutputNoLog("Error registering with operational test service: " + ex.ToString());
                }
            }
        }
        /// <summary>
        /// Manages excution of the test behaviros
        /// </summary>
        private void AsynchronousExecutionManager()
        {
            // execute ten times per second
            MMWaitableTimer mmwt = new MMWaitableTimer(100);

            // initialize
            this.testAsyncExecuteQueue          = new Queue <Behavior>();
            this.testBehaviorExecutionStopwatch = new Stopwatch();
            this.testModeRecentCompleted        = new List <TestBehaviorCompletion>();
            this.testCurrentTest      = null;
            this.testCompletionReport = null;

            // loop constantly
            while (true)
            {
                // make sre we are timing properly
                mmwt.WaitEvent.WaitOne();

                // reset values
                this.testCurrentTest      = null;
                this.testCompletionReport = null;

                // update the list of completed to only include those in last 10 seconds
                List <TestBehaviorCompletion> updatedRecent = new List <TestBehaviorCompletion>();
                foreach (TestBehaviorCompletion tbc in this.testModeRecentCompleted)
                {
                    if (this.GetVehicleState().Timestamp - tbc.CompletionTimestamp < 10.0)
                    {
                        updatedRecent.Add(tbc);
                    }
                }
                this.testModeRecentCompleted = updatedRecent;

                try
                {
                    if (!this.testComponentNeedsRoadNetwork &&
                        this.testComponentExists &&
                        testAsyncExecuteQueue.Count > 0)
                    {
                        // reset timer
                        this.testBehaviorExecutionStopwatch.Stop();
                        this.testBehaviorExecutionStopwatch.Reset();

                        // eavior
                        this.testCurrentTest = testAsyncExecuteQueue.Dequeue();

                        // thread the execution
                        this.testBehaviorExecutionThread = new Thread(TestBehaviorExecutionThread);
                        this.testBehaviorExecutionThread.IsBackground = true;
                        this.testBehaviorExecutionStopwatch.Start();
                        this.testBehaviorExecutionThread.Start();

                        // test execution time
                        while (this.testBehaviorExecutionThread.IsAlive)
                        {
                            // check time
                            if (this.testBehaviorExecutionStopwatch.ElapsedMilliseconds / 1000.0 > 3.0)
                            {
                                try
                                {
                                    ArbiterOutput.OutputNoLog("Test Behavior Execution took Longer than 3 seconds, aborting");
                                    this.testBehaviorExecutionThread.Abort();
                                }
                                catch (Exception)
                                {
                                }
                            }
                            // fine
                            else
                            {
                                // take 10ms
                                Thread.Sleep(100);
                            }
                        }

                        //  check completion report status
                        if (this.testCompletionReport != null)
                        {
                            List <TestBehaviorCompletion> updated = new List <TestBehaviorCompletion>(this.testModeRecentCompleted.ToArray());
                            updated.Add(new TestBehaviorCompletion(this.GetVehicleState().Timestamp, this.testCompletionReport, this.testCurrentTest));
                            this.testModeRecentCompleted = updated;
                        }

                        this.testCompletionReport = null;
                        this.testCurrentTest      = null;
                    }
                    else
                    {
                        try
                        {
                            this.operationalTestFacade.Ping();
                            this.testComponentExists = true;
                        }
                        catch (Exception)
                        {
                            this.testComponentExists           = false;
                            this.testComponentNeedsRoadNetwork = true;
                            this.TryOperationalTestFacadeConnect();
                        }

                        if (!this.testComponentExists || this.testComponentNeedsRoadNetwork)
                        {
                            this.TryOperationalTestFacadeConnect();
                        }
                    }
                }
                catch (Exception e)
                {
                }
            }
        }