public void Be_False_When_Car_Finishes_Lap_Second_Recording()
        {
            CarDetails carDetails = new CarDetails
            {
                CarLocationData = new CarCoordinates
                {
                    Location  = StartLine,
                    TimeStamp = 2000
                },
                PreviousLapTime = 1000
            };

            Assert.IsFalse(CarLocationProcessor.FinishedLap(carDetails));
        }
        public void Be_True_When_Car_Finishes_Lap()
        {
            CarDetails carDetails = new CarDetails
            {
                CarLocationData = new CarCoordinates
                {
                    Location  = StartLine,
                    TimeStamp = 500000
                },
                PreviousLapTime = 100000
            };

            Assert.IsTrue(CarLocationProcessor.FinishedLap(carDetails));
        }
        /// <summary>
        /// Process the Car Coordinates and update cache and publish relevant Status and Events
        /// </summary>
        /// <param name="carCoordinatesPayload"></param>
        public void Process(string carCoordinatesPayload)
        {
            CarCoordinates currentCarDetails = JsonConvert.DeserializeObject <CarCoordinates>(carCoordinatesPayload);

            if (_allCarDetailsCache.ContainsKey(currentCarDetails.CarIndex))
            {
                #region Update Car Details

                CarDetails currentCarInformation = _allCarDetailsCache[currentCarDetails.CarIndex];
                currentCarInformation.UpdateCarCoordinates(currentCarDetails);
                currentCarInformation.UpdateCarSpeed();
                currentCarInformation.UpdateRank(ReorderAllCarsAndGetCurrentCarsPosition(currentCarInformation));

                #endregion

                #region Publish Car Speed

                PublisherClient.PublishMessage("carStatus", currentCarInformation.GenerateCarStatusPayload(StatusPayloadType.Speed));

                #endregion

                #region Update Position Of Car if Changed

                if (currentCarInformation.Rank != currentCarInformation.PreviousRank)
                {
                    PublisherClient.PublishMessage("carStatus", currentCarInformation.GenerateCarStatusPayload(StatusPayloadType.Position));
                }

                #endregion

                #region Update Lap

                if (CarLocationProcessor.FinishedLap(currentCarInformation))
                {
                    PublisherClient.PublishMessage("events", currentCarInformation.GenerateCarEvent(EventType.LapComplete));

                    currentCarInformation.PreviousLapTime = currentCarDetails.TimeStamp;
                    currentCarInformation.LapNumber++;
                }

                #endregion
            }
            else
            {
                CarDetails carDetails = new CarDetails
                {
                    CarLocationData    = currentCarDetails,
                    Rank               = -1,
                    CurrentSpeed       = 0,
                    CarIndex           = currentCarDetails.CarIndex,
                    DistancedTraveled  = 0,
                    PreviousRank       = 0,
                    AverageSpeedPerLap = new Dictionary <int, double>()
                    {
                        { 1, 0.0 }
                    },
                    LapNumber       = 1,
                    PreviousLapTime = currentCarDetails.TimeStamp
                };

                _allCarDetailsCache.Add(currentCarDetails.CarIndex, carDetails);
            }
        }