/// <summary>
        /// Add a know train in T2G and might initialize the data-package embedded service.
        /// </summary>
        /// <param name="trainId">The train identifier.</param>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="isOnline">Indicates the initiale online status of the train.</param>
        /// <param name="ipAddress">The ip address of the train.</param>
        /// <param name="dataPackagePort">The data package port.</param>
        /// <param name="communicationLink">The communication link.</param>
        /// <param name="initializeEmbeddedService">Indicates if the embedded data-package service shall be initialized.</param>
        /// <param name="currentBaseline">The current baseline version.</param>
        /// <exception cref="NotImplementedException">Support to multiple train need to be implemented if needed.</exception>
        protected void InitializeTrain(string trainId, int vehicleId, bool isOnline, string ipAddress, ushort dataPackagePort, CommLinkEnum communicationLink, bool initializeEmbeddedService, string currentBaseline)
        {
            _identificationServiceStub.UpdateSystem(trainId, vehicleId, isOnline, 0, DEFAULT_MISSION, communicationLink, ipAddress);
            _vehicleInfoServiceStub.UpdateMessageData(new VersionMessage(trainId, DEFAULT_PIS_VERSION));
            BaselineMessage baseline = new BaselineMessage(trainId);

            baseline.CurrentVersion = currentBaseline;
            _vehicleInfoServiceStub.UpdateMessageData(baseline);

            MissionMessage mission = new MissionMessage(trainId, DEFAULT_MISSION, (string.IsNullOrEmpty(DEFAULT_MISSION)) ? "NI" : "MI", DEFAULT_OPERATOR_CODE);

            _vehicleInfoServiceStub.UpdateMessageData(mission);

            ServiceInfoData datapackageService = new ServiceInfoData((ushort)eServiceID.eSrvSIF_DataPackageServer, SERVICE_NAME_DATA_PACKAGE, isOnline && initializeEmbeddedService, ipAddress, dataPackagePort, (ushort)vehicleId, DEFAULT_CAR_ID);

            _vehicleInfoServiceStub.UpdateServiceData(trainId, datapackageService);

            _dataStoreServiceStub.UpdateDataStore(new ElementsDataStoreData(trainId));

            if (initializeEmbeddedService)
            {
                if (_trainDataPackageServiceStub != null)
                {
                    throw new NotImplementedException("Support to multiple train need to be implemented if needed.");
                }

                _trainDataPackageServiceStub = new TrainDataPackageServiceStub(trainId);
                Uri address = new Uri("http://" + ipAddress + ":" + dataPackagePort);
                _hostTrainDataPackageService = new ServiceHost(_trainDataPackageServiceStub, address);
                _hostTrainDataPackageService.Open();
            }
        }
        public void DistributeBaselineScenario_Nominal()
        {
            const string FUTURE_VERSION = "1.0.0.0";

            // Common initialization
            CreateT2GServicesStub();
            _dataStoreServiceStub.InitializeRemoteDataStoreMockWithDefaultBehavior();
            InitializeTrain(TRAIN_NAME_1, TRAIN_VEHICLE_ID_1, true, TRAIN_IP_1, TRAIN_DATA_PACKAGE_PORT_1);
            InitializeDataPackageService(false);
            InitializePISGroundSession();
            WaitPisGroundIsConnectedWithT2G();
            WaitTrainOnlineWithPISGround(TRAIN_NAME_1, true);

            // Initializations specific to this test.
            ElementsDataStoreData data = new ElementsDataStoreData(TRAIN_NAME_1);

            data.FutureBaseline = FUTURE_VERSION;
            data.FutureBaselineActivationDate = RemoteDataStoreDataBase.ToString(DateTime.Today);
            data.FutureBaselineExpirationDate = RemoteDataStoreDataBase.ToString(DateTime.Now.AddMinutes(20));

            _dataStoreServiceStub.UpdateDataStore(data);
            _dataStoreServiceStub.AddBaselineToRemoteDataStore(FUTURE_VERSION);

            // Request the datapackage service to distribute the baseline
            DataPackageResult result = _datapackageServiceStub.distributeBaseline(_pisGroundSessionId, null, new TargetAddressType(TRAIN_NAME_1), CreateDistributionAttribute(), false);

            Assert.AreEqual(DataPackageErrorEnum.REQUEST_ACCEPTED, result.error_code, "Distribute baseline to train {0} does not returned the expected value", TRAIN_NAME_1);

            // Wait that folder on T2G was created

            Assert.That(() => _fileTransferServiceStub.LastCreatedFolder.HasValue, Is.True.After(30 * ONE_SECOND, ONE_SECOND / 4), "Distribute baseline to train {0} failure. Transfer folder on T2G service not created", TRAIN_NAME_1);
            int transferFolderId = _fileTransferServiceStub.LastCreatedFolder.Value;

            _fileTransferServiceStub.LastCreatedFolder = null;
            Assert.That(() => _fileTransferServiceStub.LastCreatedTransfer.HasValue, Is.True.After(30 * ONE_SECOND, ONE_SECOND / 4), "Distribute baseline to train {0} failure. Transfer task on T2G service not created", TRAIN_NAME_1);
            int transferTaskId = _fileTransferServiceStub.LastCreatedTransfer.Value;

            _fileTransferServiceStub.LastCreatedTransfer = null;

            _fileTransferServiceStub.PerformTransferProgression();

            // Probleme
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.TRANSFER_PLANNED);
            while (_fileTransferServiceStub.IsTaskRunning(transferTaskId))
            {
                _fileTransferServiceStub.PerformTransferProgression();
                BaselineProgressStatusEnum expectedProgress = _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress;
                VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, expectedProgress);
                Thread.Sleep(ONE_SECOND / 4);
            }

            Thread.Sleep(5 * ONE_SECOND);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.TRANSFER_COMPLETED);


            // Simulate that train retrieved the baseline on embedded side.

            BaselineMessage baselineInfo = new BaselineMessage(TRAIN_NAME_1);

            baselineInfo.CurrentVersion = DEFAULT_BASELINE;
            baselineInfo.FutureVersion  = FUTURE_VERSION;
            _vehicleInfoServiceStub.UpdateMessageData(baselineInfo);

            WaitBaselineStatusBecomeInState(TRAIN_NAME_1, BaselineProgressStatusEnum.DEPLOYED);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.DEPLOYED);

            // Simulate that train replaced the current baseline with the future.
            baselineInfo.ArchivedVersion = baselineInfo.CurrentVersion;
            baselineInfo.CurrentVersion  = baselineInfo.FutureVersion;
            baselineInfo.FutureVersion   = string.Empty;
            _vehicleInfoServiceStub.UpdateMessageData(baselineInfo);

            WaitBaselineStatusBecomeInState(TRAIN_NAME_1, BaselineProgressStatusEnum.UPDATED);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, FUTURE_VERSION, "0.0.0.0", Guid.Empty, 0, BaselineProgressStatusEnum.UPDATED);
        }
        public void DistributeBaselineScenario_WaitForCommunicationLink_RestartPisGround_ThenDistributionComplete()
        {
            const string FUTURE_VERSION = "1.0.0.0";

            // Common initialization
            CreateT2GServicesStub();
            _dataStoreServiceStub.InitializeRemoteDataStoreMockWithDefaultBehavior();
            InitializeTrain(TRAIN_NAME_1, TRAIN_VEHICLE_ID_1, true, TRAIN_IP_1, TRAIN_DATA_PACKAGE_PORT_1, CommLinkEnum.notApplicable);
            InitializeDataPackageService(false);
            InitializePISGroundSession();
            WaitPisGroundIsConnectedWithT2G();
            WaitTrainOnlineWithPISGround(TRAIN_NAME_1, true);

            // Initializations specific to this test.
            ElementsDataStoreData data = new ElementsDataStoreData(TRAIN_NAME_1);

            data.FutureBaseline = FUTURE_VERSION;
            data.FutureBaselineActivationDate = RemoteDataStoreDataBase.ToString(DateTime.Today);
            data.FutureBaselineExpirationDate = RemoteDataStoreDataBase.ToString(DateTime.Now.AddMinutes(20));

            _dataStoreServiceStub.UpdateDataStore(data);
            _dataStoreServiceStub.AddBaselineToRemoteDataStore(FUTURE_VERSION);

            // Request the datapackage service to distribute the baseline
            DataPackageResult result = _datapackageServiceStub.distributeBaseline(_pisGroundSessionId, null, new TargetAddressType(TRAIN_NAME_1), CreateDistributionAttribute(), false);

            Assert.AreEqual(DataPackageErrorEnum.REQUEST_ACCEPTED, result.error_code, "Distribute baseline to train {0} does not returned the expected value", TRAIN_NAME_1);

            // Wait that folder on T2G was created

            Assert.That(() => _fileTransferServiceStub.LastCreatedFolder.HasValue, Is.True.After(30 * ONE_SECOND, ONE_SECOND / 4), "Distribute baseline to train {0} failure. Transfer folder on T2G service not created", TRAIN_NAME_1);
            int transferFolderId = _fileTransferServiceStub.LastCreatedFolder.Value;

            _fileTransferServiceStub.LastCreatedFolder = null;
            Assert.That(() => _fileTransferServiceStub.LastCreatedTransfer.HasValue, Is.True.After(30 * ONE_SECOND, ONE_SECOND / 4), "Distribute baseline to train {0} failure. Transfer task on T2G service not created", TRAIN_NAME_1);
            int transferTaskId = _fileTransferServiceStub.LastCreatedTransfer.Value;

            _fileTransferServiceStub.LastCreatedTransfer = null;

            _fileTransferServiceStub.PerformTransferProgression();

            while (_fileTransferServiceStub.GetTask(transferTaskId).taskPhase == T2GServiceInterface.FileTransfer.taskPhaseEnum.acquisitionPhase)
            {
                VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress);
                _fileTransferServiceStub.PerformTransferProgression();
                Assert.IsNull(_fileTransferServiceStub.LastCreatedFolder, "Folder created while expecting not");
                Assert.IsNull(_fileTransferServiceStub.LastCreatedTransfer, "Transfer task created while expecting not");
                Assert.IsTrue(_fileTransferServiceStub.IsTaskRunning(transferTaskId), "The transfer task is not running as expected");
                Thread.Sleep(ONE_SECOND / 4);
            }
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress);

            // Stop data package service.
            StopDataPackageService();

            // Wait 2 seconds
            Thread.Sleep(2 * ONE_SECOND);

            // Restart the datapackage service
            InitializeDataPackageService(true);

            WaitPisGroundIsConnectedWithT2G();
            WaitTrainOnlineWithPISGround(TRAIN_NAME_1, true);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress);

            // Wait 2 seconds
            Thread.Sleep(2 * ONE_SECOND);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress);

            // Update the communication link of the train
            _identificationServiceStub.UpdateSystem(TRAIN_NAME_1, TRAIN_VEHICLE_ID_1, true, 0, DEFAULT_MISSION, CommLinkEnum.wifi, TRAIN_IP_1);

            _fileTransferServiceStub.PerformTransferProgression();
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, _fileTransferServiceStub.GetTask(transferTaskId).BaselineProgress);
            _fileTransferServiceStub.PerformTransferProgression();
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.TRANSFER_IN_PROGRESS);

            Assert.That(() => { _fileTransferServiceStub.PerformTransferProgression(); return(_fileTransferServiceStub.GetTask(transferTaskId).IsInFinalState); }, Is.True.After(10 * ONE_SECOND, ONE_SECOND / 4), "Transfer does not complete as expected");
            Assert.IsNull(_fileTransferServiceStub.LastCreatedFolder, "Folder created while expecting not");
            Assert.IsNull(_fileTransferServiceStub.LastCreatedTransfer, "Transfer task created while expecting not");
            {
                TransferTaskInfo task = _fileTransferServiceStub.GetTask(transferTaskId);
                Assert.AreEqual(TaskStateEnum.taskCompleted, task.taskState, "Transfer does not complete as expected");
            }
            WaitBaselineStatusBecomeInState(TRAIN_NAME_1, BaselineProgressStatusEnum.TRANSFER_COMPLETED);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.TRANSFER_COMPLETED);

            // Simulate that train retrieved the baseline on embedded side.

            BaselineMessage baselineInfo = new BaselineMessage(TRAIN_NAME_1);

            baselineInfo.CurrentVersion = DEFAULT_BASELINE;
            baselineInfo.FutureVersion  = FUTURE_VERSION;
            _vehicleInfoServiceStub.UpdateMessageData(baselineInfo);

            WaitBaselineStatusBecomeInState(TRAIN_NAME_1, BaselineProgressStatusEnum.DEPLOYED);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, DEFAULT_BASELINE, FUTURE_VERSION, result.reqId, transferTaskId, BaselineProgressStatusEnum.DEPLOYED);

            // Simulate that train replaced the current baseline with the future.
            baselineInfo.ArchivedVersion = baselineInfo.CurrentVersion;
            baselineInfo.CurrentVersion  = baselineInfo.FutureVersion;
            baselineInfo.FutureVersion   = string.Empty;
            _vehicleInfoServiceStub.UpdateMessageData(baselineInfo);

            WaitBaselineStatusBecomeInState(TRAIN_NAME_1, BaselineProgressStatusEnum.UPDATED);
            VerifyTrainBaselineStatusInHistoryLog(TRAIN_NAME_1, true, FUTURE_VERSION, "0.0.0.0", Guid.Empty, 0, BaselineProgressStatusEnum.UPDATED);
        }
        public void TrainBaselineStatusScenario_OnMessageChangedUpdateTheBaselineInfo()
        {
            TrainBaselineStatusData valueTrain1 = new TrainBaselineStatusData(TRAIN_NAME_1, TRAIN_VEHICLE_ID_1, true, DEFAULT_BASELINE, BaselineStatusUpdater.NoBaselineVersion, DEFAULT_PIS_VERSION, BaselineProgressStatusEnum.UNKNOWN);
            TrainBaselineStatusData valueTrain2 = new TrainBaselineStatusData(TRAIN_NAME_2, TRAIN_VEHICLE_ID_2, true, "5.4.3.3", BaselineStatusUpdater.NoBaselineVersion, DEFAULT_PIS_VERSION, BaselineProgressStatusEnum.UNKNOWN);
            TrainBaselineStatusData valueTrain3 = new TrainBaselineStatusData(TRAIN_NAME_0, TRAIN_VEHICLE_ID_0, false, "1.0.0.0", BaselineStatusUpdater.NoBaselineVersion, DEFAULT_PIS_VERSION, BaselineProgressStatusEnum.UNKNOWN);
            Dictionary <string, TrainBaselineStatusData> expectedStatuses = new Dictionary <string, TrainBaselineStatusData>();

            expectedStatuses.Add(valueTrain1.TrainId, valueTrain1.Clone());
            expectedStatuses.Add(valueTrain2.TrainId, valueTrain2.Clone());
            expectedStatuses.Add(valueTrain3.TrainId, valueTrain3.Clone());

            // Initialize services
            CreateT2GServicesStub();

            _dataStoreServiceStub.InitializeRemoteDataStoreMockWithDefaultBehavior();

            InitializeTrain(TRAIN_NAME_1, TRAIN_VEHICLE_ID_1, true, TRAIN_IP_1, TRAIN_DATA_PACKAGE_PORT_1, commLinkEnum._2G3G, true);
            InitializeTrain(TRAIN_NAME_0, TRAIN_VEHICLE_ID_0, false, TRAIN_IP_0, TRAIN_DATA_PACKAGE_PORT_0, commLinkEnum.wifi, false, "1.0.0.0");
            InitializeTrain(TRAIN_NAME_2, TRAIN_VEHICLE_ID_2, true, TRAIN_IP_2, TRAIN_DATA_PACKAGE_PORT_2, commLinkEnum._2G3G, false, "5.4.3.3");

            InitializeDataPackageService(false);
            InitializePISGroundSession();

            // Wait that history log was on expected status.

            WaitTrainBaselineStatusesEquals(expectedStatuses, "Online statuses of train not updated in train baseline status when PIS-Ground connect with T2G");


            // Update current baseline message of TRAIN-0
            valueTrain3.CurrentBaselineVersion    = "8.8.8.8";
            expectedStatuses[valueTrain1.TrainId] = valueTrain1.Clone();
            expectedStatuses[valueTrain2.TrainId] = valueTrain2.Clone();
            expectedStatuses[valueTrain3.TrainId] = valueTrain3.Clone();
            BaselineMessage baseline = new BaselineMessage(valueTrain3.TrainId);

            baseline.CurrentVersion = valueTrain3.CurrentBaselineVersion;
            baseline.FutureVersion  = valueTrain3.FutureBaselineVersion;
            _vehicleInfoServiceStub.UpdateMessageData(baseline);

            WaitTrainBaselineStatusesEquals(expectedStatuses, "T2G - OnMessageChanged does not update the current baseline version in train baseline statuses database.");

            // Update future baseline pis.version message of TRAIN-1
            valueTrain1.FutureBaselineVersion     = "7.7.7.7";
            expectedStatuses[valueTrain1.TrainId] = valueTrain1.Clone();
            expectedStatuses[valueTrain2.TrainId] = valueTrain2.Clone();
            expectedStatuses[valueTrain3.TrainId] = valueTrain3.Clone();
            baseline = new BaselineMessage(valueTrain1.TrainId);
            baseline.CurrentVersion = valueTrain1.CurrentBaselineVersion;
            baseline.FutureVersion  = valueTrain1.FutureBaselineVersion;
            _vehicleInfoServiceStub.UpdateMessageData(baseline);

            WaitTrainBaselineStatusesEquals(expectedStatuses, "T2G - OnMessageChanged does not update the future baseline version in train baseline statuses database.");

            // Update current and future baseline version of TRAIN-2
            valueTrain2.FutureBaselineVersion     = "9.8.7.6";
            valueTrain2.CurrentBaselineVersion    = "5.4.3.2";
            expectedStatuses[valueTrain1.TrainId] = valueTrain1.Clone();
            expectedStatuses[valueTrain2.TrainId] = valueTrain2.Clone();
            expectedStatuses[valueTrain3.TrainId] = valueTrain3.Clone();
            baseline = new BaselineMessage(valueTrain2.TrainId);
            baseline.CurrentVersion = valueTrain2.CurrentBaselineVersion;
            baseline.FutureVersion  = valueTrain2.FutureBaselineVersion;
            _vehicleInfoServiceStub.UpdateMessageData(baseline);

            WaitTrainBaselineStatusesEquals(expectedStatuses, "T2G - OnMessageChanged does not update current and future baseline version in train baseline statuses database.");
        }