public async Task <VehicleActorError> ReserveAsync(string user, DateTime startReservation, DateTime endReservation, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(user))
            {
                throw new ArgumentException(nameof(user));
            }

            if (startReservation >= endReservation)
            {
                return(VehicleActorError.ReservationDatesWrong);
            }

            var info = await GetVehicleDataFromStateAsync(cancellationToken);

            if (info == null)
            {
                return(VehicleActorError.VehicleNotExists);
            }

            var currentState = await GetVehicleStateFromStateAsync(cancellationToken);

            if (currentState == VehicleActorInterface.VehicleState.Busy)
            {
                return(VehicleActorError.VehicleBusy);
            }
            if (currentState == VehicleActorInterface.VehicleState.NotAvailable)
            {
                return(VehicleActorError.VehicleNotAvailable);
            }

            var actorProxy = this.actorFactory.Create <IUserActor>(new ActorId(user),
                                                                   new Uri(UriConstants.UserActorUri));

            var rentinfo = new UserActorInterfaces.RentInfo()
            {
                DailyCost = info.DailyCost,
                Plate     = this.Id.ToString(),
                StartRent = startReservation,
                EndRent   = endReservation
            };

            //var response = await actorProxy.RentVehicleAsync(rentinfo, cancellationToken);

            var response = await actorProxy.CallWithPolicyForTimeoutAsync <IUserActor, UserActorError>(c => actorProxy.RentVehicleAsync(rentinfo, c),
                                                                                                       5, i => TimeSpan.FromMilliseconds(100 * i), cancellationToken);

            if (response == UserActorError.UserNotValid)
            {
                return(VehicleActorError.UserNotValid);
            }

            if (response != UserActorError.Ok)
            {
                return(VehicleActorError.GenericError);
            }

            VehicleActorInterface.RentInfo rentInfo = new VehicleActorInterface.RentInfo()
            {
                User = user, StartDate = startReservation, EndDate = endReservation
            };
            await this.SetCurrentRentInfoIntoStateAsync(rentInfo, cancellationToken);

            await this.SetVehicleStateIntoStateAsync(VehicleActorInterface.VehicleState.Busy, cancellationToken);

            var result = await this.vehiclesServiceProxy.UpdateVehicleStateAsync(this.Id.ToString(),
                                                                                 VehiclesService.Interfaces.VehicleState.Busy, cancellationToken);

            return(VehicleActorError.Ok);
        }
 private Task SetCurrentRentInfoIntoStateAsync(VehicleActorInterface.RentInfo info, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(this.StateManager.SetStateAsync <VehicleActorInterface.RentInfo>(CurrentRentInfoKeyName, info, cancellationToken));
 }