/// <summary>
        ///
        /// </summary>
        /// <param name="operatorInfo"></param>
        /// <returns></returns>
        /// <exception cref="FriendlyException"></exception>
        public async Task <OperatorInfoViewModel> GetOperatorInfoAsync(OperatorInfoViewModel operatorInfo)
        {
            string debugStr = "";

            Logger.WriteDebug("GetOperatorInfoAsync called.");

            try
            {
                if (!operatorInfo.Agreed)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (string.IsNullOrWhiteSpace(operatorInfo.DeviceGuid))
                {
                    throw new FriendlyException(FriendlyExceptionType.DeviceIsNotSupported);
                }

                if (!operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.Badge))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                //if (!operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.CardNumber))
                //    throw new FriendlyException(FriendlyExceptionType.AccessDenied);


                if (operatorInfo.Validating && string.IsNullOrWhiteSpace(operatorInfo.DeviceSessionId))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedSessionMismatch);
                }

                // --------------------------------------some sanity check!
                if ((operatorInfo.FirstName?.Length ?? 0) > 255)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "FirstName is too long.");
                }
                if ((operatorInfo.LastName?.Length ?? 0) > 255)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "LastName is too long.");
                }
                if ((operatorInfo.Badge?.Length ?? 0) > 10)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Badge is too long.");
                }
                //if ((operatorInfo.CardNumber?.Length ?? 0) > 25)
                //    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Card number is too long.");

                //----------------------------------------



                var badge = operatorInfo.Badge?.Trim().PadLeft(6, '0');
                debugStr = "Before getting Demo User for badge: " + badge;

                var user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == badge);

                if (user == null)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessHasBeenRevoked, "", debugStr);
                }
                if (!user.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, "", debugStr);
                }

                //var demoUser = await IsDemoUserAsync(operatorInfo.FirstName, operatorInfo.LastName, badge);
                var demoUser = user.IsDemo.GetValueOrDefault(false);

                debugStr = "After getting Demo User: "******"After getting Employee, DemoUser: {demoUser}, Found:{(employee != null)}";

                if (employee == null && !demoUser)
                {
                    var s = $"GetOperatorInfo. Employee not found." + $"debugStr: {debugStr}";
                    Logger.Write(s);
                    WriteLog(operatorInfo, s);
                    //await InvalidateOperatorAsync(badge);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }
                else if (employee != null && (
                             !string.Equals(employee.LastName, operatorInfo.LastName, StringComparison.OrdinalIgnoreCase) ||
                             //!string.Equals(employeeCardNumber, cardNumber, StringComparison.OrdinalIgnoreCase) ||

                             //!employee.SecurityCardEnabled.GetValueOrDefault(false) ||  // After the issue raise with one of the employees "Joseph Seibel", Michael decided to disabled this check
                             (!string.Equals(employee.FirstName, operatorInfo.FirstName, StringComparison.OrdinalIgnoreCase) &&
                              !string.Equals(employee.MiddleName, operatorInfo.FirstName, StringComparison.OrdinalIgnoreCase)))
                         )
                {
                    //var s =  $"GetOperatorInfo. Employee badge: {badge} found but names or card # {cardNumber} were not match.";
                    var s = $"GetOperatorInfo. Employee badge: {badge} found but names were not match.";
                    s += $"Entered: FirstName: {employee?.FirstName??""}, LastName: {employee?.LastName??""}";
                    Logger.Write(s);
                    WriteLog(operatorInfo, s);
                    //await InvalidateOperatorAsync(badge);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                if (demoUser)
                {
                    CurrentUserName = "******";
                }
                else
                {
                    CurrentUserName = employee.Name;
                }


                var device = await RestroomUnitOfWork.Get <Device>()
                             .FirstOrDefaultAsync(m => m.DeviceGuid == operatorInfo.DeviceGuid);

                //User user = await RestroomUnitOfWork.Get<User>().FirstOrDefaultAsync(m => m.Badge == badge);

                //if (!string.Equals(user?.LastName, operatorInfo.LastName) ||
                //    (!string.Equals(user?.FirstName, operatorInfo.FirstName) &&
                //     !string.Equals(user?.MiddleName, operatorInfo.FirstName)))
                //    user = null;

                //debugStr = $"after getting device and user. DeviceGuid:{operatorInfo.DeviceGuid}, Badge: {badge}";

                if (!demoUser)
                {
                    if (operatorInfo.Validating && device == null)
                    {
                        throw new FriendlyException(FriendlyExceptionType.AccessDenied, "", debugStr);
                    }

                    if (device != null && !device.Active)
                    {
                        throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive,
                                                    $"debugStr: {debugStr}");
                    }
                }

                //if (user != null && !user.Active)
                //    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive,"", debugStr);


                if (operatorInfo.Validating && (device == null || !device.Active ||
                                                device.DeviceSessionId != operatorInfo.DeviceSessionId))
                {
                    if (device == null)
                    {
                        throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                    }
                    if (!device.Active)
                    {
                        throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive);
                    }
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedSessionMismatch);
                }

                if (operatorInfo.Validating && (user == null || !user.Active))
                {
                    throw new FriendlyException(user == null
                        ? FriendlyExceptionType.AccessHasBeenRevoked
                        : FriendlyExceptionType.AccessDeniedNotActive);
                }

                UserDevice userDevice = null;
                if (device != null)
                {
                    userDevice = await RestroomUnitOfWork.Get <UserDevice>()
                                 .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId);
                }
                if (device == null)
                {
                    device = new Device
                    {
                        Active      = true, //demoUser,
                        DeviceGuid  = operatorInfo.DeviceGuid,
                        DeviceModel = operatorInfo.DeviceModel,
                        DeviceOS    = operatorInfo.DeviceOS,
                        LastUsed    = DateTime.Now
                    };
                    device.DeviceSessionId = Guid.NewGuid().ToString(); //CreateDeviceSessionId(operatorInfo);
                }
                else
                {
                    //try
                    //{
                    if (operatorInfo.Validating && device.DeviceSessionId != operatorInfo.DeviceSessionId)
                    {
                        Logger.WriteError($"Badge:{badge}, Validating but sessions are not match!");
                        throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                    }

                    if (device.DeviceSessionId != operatorInfo.DeviceSessionId)
                    {
                        device.DeviceSessionId = Guid.NewGuid().ToString();
                    }

                    //var ticket = FormsAuthentication.Decrypt(device.DeviceSessionId);
                    //if (ticket == null || ticket.Name != operatorInfo.DeviceGuid)
                    //    throw new FriendlyException(FriendlyExceptionType.AccessDenied);

                    //if (ticket.Expired)
                    //    device.DeviceSessionId = CreateDeviceSessionId(operatorInfo);
                    //}
                    //catch (Exception ex)
                    //{
                    //    Logger.WriteError(ex.Message);
                    //    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                    //}
                }

                if (user == null)
                {
                    user = new User
                    {
                        Active = true,
                        Badge  = badge,
                    };
                }

                user.SecurityCardFormatted = employee?.SecurityCardFormatted;
                user.FirstName             = demoUser?"Demo":(employee?.FirstName ?? "");
                user.LastName   = demoUser?"User":(employee?.LastName ?? "");
                user.MiddleName = employee?.MiddleName ?? "";


                var confirmation = new Confirmation
                {
                    Badge            = badge,
                    Agreed           = operatorInfo.Agreed,
                    IncidentDateTime = operatorInfo.IncidentDateTime,
                    DeviceId         = operatorInfo.DeviceGuid,
                    Active           = true
                };


                device.LastUsed = DateTime.Now;

                user         = RestroomUnitOfWork.PrepUser(user);
                device       = RestroomUnitOfWork.PrepDevice(device);
                confirmation = RestroomUnitOfWork.PrepConfirmation(confirmation);
                await RestroomUnitOfWork.SaveChangesAsync();

                if (userDevice == null)
                {
                    userDevice        = new UserDevice();
                    userDevice.Active =
                        true; //demoUser || device.DeviceId==default(long) || (!string.IsNullOrWhiteSpace(operatorInfo.DeviceSessionId) && operatorInfo.DeviceSessionId == device.DeviceSessionId);
                }

                userDevice.LastLogon = DateTime.Now;
                userDevice.UserId    = user.UserId;
                userDevice.DeviceId  = device.DeviceId;

                userDevice = await RestroomUnitOfWork.SaveUserDeviceAsync(userDevice);



                operatorInfo.DeviceSessionId = device.DeviceSessionId;
                operatorInfo.SessionApproved = user.Active && userDevice.Active && device.Active;
            }
            catch (FriendlyException ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                if (ex.ExceptionType != FriendlyExceptionType.AccessDeniedNotActive)
                {
                    throw;
                }
                operatorInfo.SessionApproved = false;
            }
            catch (DbEntityValidationException ex)
            {
                Logger.WriteError("DbEntityValidationException, debugStr:" + debugStr + ", Error:" + ex.Message);
                foreach (var eve in ex.EntityValidationErrors)
                {
                    Logger.WriteError($"Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:");
                    foreach (var ve in eve.ValidationErrors)
                    {
                        Logger.WriteError($"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\"");
                    }
                }
                operatorInfo.SessionApproved = false;
            }
            catch (Exception ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                operatorInfo.SessionApproved = false;
            }
            return(operatorInfo);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="FriendlyException"></exception>
        public async Task DisclaimerResponse(DisclaimerViewModel model)
        {
            const string methodName = "DisclaimerResponse";
            string       debugStr   = "";

            Logger.WriteDebug($"{methodName} called.");

            try
            {
                if (model == null)
                {
                    throw new FriendlyException(FriendlyExceptionType.InvalidModelState);
                }

                if (!model.Agreed)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (string.IsNullOrWhiteSpace(model.DeviceSessionId))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }

                if (string.IsNullOrWhiteSpace(model.DeviceGuid))
                {
                    throw new FriendlyException(FriendlyExceptionType.DeviceIsNotSupported);
                }

                if (string.IsNullOrWhiteSpace(model.Badge))
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                // --------------------------------------some sanity check!
                if (model.Badge?.Length > 10)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied, "Badge is too long.");
                }

                //----------------------------------------
                var badge = model.Badge?.Trim().PadLeft(6, '0');
                debugStr = "Before getting Demo User for badge: " + badge;

                var user = await RestroomUnitOfWork.Get <User>().FirstOrDefaultAsync(m => m.Badge == badge);

                if (user == null)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessHasBeenRevoked, "", debugStr);
                }
                if (!user.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, "", debugStr);
                }

                //var demoUser = await IsDemoUserAsync(operatorInfo.FirstName, operatorInfo.LastName, badge);
                var demoUser = user.IsDemo.GetValueOrDefault(false);

                debugStr = "After getting Demo User: "******"After getting Employee, DemoUser: {demoUser}, Found:{(employee != null)}";


                if (employee == null && !demoUser)
                {
                    var s = $"{methodName}. Employee not found." + $"debugStr: {debugStr}";
                    Logger.Write(s);
                    WriteLog(model, s);
                    throw new FriendlyException(FriendlyExceptionType.AccessDenied);
                }


                if (demoUser)
                {
                    CurrentUserName = "******";
                }
                else
                {
                    CurrentUserName = employee.Name;
                }

                debugStr = $"Getting device for {model.DeviceGuid}";
                var device = await RestroomUnitOfWork.Get <Device>()
                             .FirstOrDefaultAsync(m => m.DeviceGuid == model.DeviceGuid);

                if (device == null || !device.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"debugStr: {debugStr}");
                }

                debugStr = $"Getting userDevice for device:{model.DeviceGuid} and user: {user.UserId}";
                var userDevice = await RestroomUnitOfWork.Get <UserDevice>()
                                 .FirstOrDefaultAsync(m => m.DeviceId == device.DeviceId && m.UserId == user.UserId);

                if (userDevice == null || !userDevice.Active)
                {
                    throw new FriendlyException(FriendlyExceptionType.AccessDeniedNotActive, $"debugStr: {debugStr}");
                }



                var confirmation = new Confirmation
                {
                    Badge            = badge,
                    Agreed           = model.Agreed,
                    IncidentDateTime = model.IncidentDateTime,
                    DeviceId         = model.DeviceGuid,
                    SessionId        = model.DeviceSessionId,
                    Active           = true
                };

                RestroomUnitOfWork.PrepConfirmation(confirmation);
                await RestroomUnitOfWork.SaveChangesAsync();
            }
            catch (FriendlyException ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                throw;
            }
            catch (DbEntityValidationException ex)
            {
                Logger.WriteError("DbEntityValidationException, debugStr:" + debugStr + ", Error:" + ex.Message);
                foreach (var eve in ex.EntityValidationErrors)
                {
                    Logger.WriteError($"Entity of type \"{eve.Entry.Entity.GetType().Name}\" in state \"{eve.Entry.State}\" has the following validation errors:");
                    foreach (var ve in eve.ValidationErrors)
                    {
                        Logger.WriteError($"- Property: \"{ve.PropertyName}\", Error: \"{ve.ErrorMessage}\"");
                    }
                }
                throw new FriendlyException(FriendlyExceptionType.Other, "Server could not process your request. please try again later.");
            }
            catch (Exception ex)
            {
                Logger.WriteError("debugStr:" + debugStr + ", Error:" + ex.Message);
                throw new FriendlyException(FriendlyExceptionType.Other, "Server could not process your request. please try again later.");
            }
        }