public async Task <Result <string> > GetProfileImageURL(string userId)
        {
            string cacheKey = string.Format(URL_CACHE_KEY, userId);

            if (_memoryCache.TryGetValue(cacheKey, out string imageUrl))
            {
                return(Result.Ok(imageUrl));
            }

            BaseSpecification <UserImageEntity> userImageSpecification = new BaseSpecification <UserImageEntity>();

            userImageSpecification.AddFilter(x => x.UserId == userId);

            UserImageEntity userImage = await _userImageRepository.SingleOrDefault(userImageSpecification);

            if (userImage == null)
            {
                _logger.LogError($"No profile image. UserId {userId}");

                return(Result.Fail <string>("no_profile_image", "No Profile image"));
            }

            _memoryCache.Set(cacheKey, userImage.URL, IMAGE_IN_CACHE_TIME_SPAN);

            return(Result.Ok(userImage.URL));
        }
        public async Task <Result> Remove(string userId)
        {
            IBaseSpecification <UserImageEntity, UserImageEntity> specification = SpecificationBuilder
                                                                                  .Create <UserImageEntity>()
                                                                                  .Where(x => x.UserId == userId)
                                                                                  .Select(x => new UserImageEntity(
                                                                                              x.Id))
                                                                                  .Build();

            UserImageEntity userImage = await _userImageDAO.SingleOrDefault(specification);

            if (userImage == null)
            {
                _logger.LogWarning($"User does not have a profile image. UserId {userId}");
                return(Result.Ok());
            }

            bool removeResult = await _userImageDAO.Remove(userImage);

            if (!removeResult)
            {
                _logger.LogError($"Failed to remove user image");
                return(Result.Fail(FAILED_TO_REMOVE_USER_IMAGE));
            }

            return(Result.Ok());
        }
        public async Task <Core.Models.Result.Result <string> > GetProfileImageURL(string userId)
        {
            string cacheKey = string.Format(URL_CACHE_KEY, userId);

            if (_memoryCache.TryGetValue(cacheKey, out string imageUrl))
            {
                return(Result.Ok <string>(imageUrl).ToOldResult());
            }

            IBaseSpecification <UserImageEntity, UserImageEntity> getUserImageSpecification = SpecificationBuilder
                                                                                              .Create <UserImageEntity>()
                                                                                              .Where(x => x.UserId == userId)
                                                                                              .Build();

            UserImageEntity userImage = await _userImageDAO.SingleOrDefault(getUserImageSpecification);

            if (userImage == null)
            {
                _logger.LogError($"No profile image. UserId {userId}");

                return(Result.Fail <string>(PROFILE_IMAGE_NOT_FOUND).ToOldResult());
            }

            _memoryCache.Set(cacheKey, userImage.URL, IMAGE_IN_CACHE_TIME_SPAN);

            return(Result.Ok <string>(userImage.URL).ToOldResult());
        }
        public async Task <Core.Models.Result.Result <FileData> > GetProfileImage(string userId)
        {
            string cacheKey = string.Format(BLOBL_CACHE_KEY, userId);

            if (_memoryCache.TryGetValue(cacheKey, out FileData image))
            {
                return(Result.Ok(image).ToOldResult());
            }

            IBaseSpecification <UserImageEntity, UserImageEntity> getUserImageSpecification = SpecificationBuilder
                                                                                              .Create <UserImageEntity>()
                                                                                              .Where(x => x.UserId == userId)
                                                                                              .Build();

            UserImageEntity userImage = await _userImageDAO.SingleOrDefault(getUserImageSpecification);

            if (userImage == null)
            {
                _logger.LogInformation($"No profile image. UserId {userId}");

                Result <FileData> defaultImage = await _defaultProfileImageService.Get();

                if (defaultImage.Failure)
                {
                    return(Result.Fail <FileData>(defaultImage).ToOldResult());
                }

                _memoryCache.Set(cacheKey, defaultImage.Value, IMAGE_IN_CACHE_TIME_SPAN);

                return(Result.Ok(defaultImage.Value).ToOldResult());
            }

            FileData fileData = new FileData(
                fileName: userImage.FileName,
                file: userImage.BlobImage);

            _memoryCache.Set(cacheKey, fileData, IMAGE_IN_CACHE_TIME_SPAN);

            return(Result.Ok(fileData).ToOldResult());
        }
        public async Task <Result <FileData> > GetProfileImage(string userId)
        {
            string cacheKey = string.Format(BLOBL_CACHE_KEY, userId);

            if (_memoryCache.TryGetValue(cacheKey, out FileData image))
            {
                return(Result.Ok(image));
            }

            BaseSpecification <UserImageEntity> userImageSpecification = new BaseSpecification <UserImageEntity>();

            userImageSpecification.AddFilter(x => x.UserId == userId);

            UserImageEntity userImage = await _userImageRepository.SingleOrDefault(userImageSpecification);

            if (userImage == null)
            {
                _logger.LogError($"No profile image. UserId {userId}");

                Result <FileData> defaultImage = await GetDefaultImage();

                if (defaultImage.Failure)
                {
                    return(Result.Fail <FileData>(defaultImage.Errors));
                }

                _memoryCache.Set(cacheKey, defaultImage.Value, IMAGE_IN_CACHE_TIME_SPAN);

                return(Result.Ok(defaultImage.Value));
            }

            FileData fileData = new FileData(
                fileName: userImage.FileName,
                file: userImage.BlobImage);

            _memoryCache.Set(cacheKey, fileData, IMAGE_IN_CACHE_TIME_SPAN);

            return(Result.Ok(fileData));
        }
        public async Task <Result> UpdateProfileImage(string userId, UploadProfileImageRequest uploadProfileImageRequest)
        {
            if (uploadProfileImageRequest == null || uploadProfileImageRequest.File == null)
            {
                _logger.LogWarning($"No image. UserId {userId}");
                return(Result.Fail("no_profile_image", "No Image"));
            }

            //TODO: changed how image format is validated
            string imageExtension = Path.GetExtension(uploadProfileImageRequest.File.FileName);

            if (!VALID_IMAGE_FORMATS.Contains(imageExtension.ToUpper()))
            {
                _logger.LogWarning($"Invalid image format. UserId {userId}, image extension {imageExtension}");
                return(Result.Fail("profile_image_invalid_format", "Image is invalid, please select '.JPG' or '.PNG' image format."));
            }

            if (uploadProfileImageRequest.File.Length > _identityUIOptions.MaxProfileImageSize)
            {
                _logger.LogWarning($"Image is to big. UserId {userId}, image size {uploadProfileImageRequest.File.Length}");
                return(Result.Fail("image_is_to_big", $"Image is to big. Max image size {_identityUIOptions.MaxProfileImageSize / 1024} kB"));
            }

            if (uploadProfileImageRequest.File.FileName.Length > 250)
            {
                _logger.LogWarning($"Image name is to long. Image name length {uploadProfileImageRequest.File.FileName.Length}");
                return(Result.Fail("image_name_to_long", "Image name to long"));
            }

            byte[] image;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                await uploadProfileImageRequest.File.CopyToAsync(memoryStream);

                image = memoryStream.ToArray();
            }

            string urlCacheKey  = string.Format(URL_CACHE_KEY, userId);
            string blobCacheKey = string.Format(BLOBL_CACHE_KEY, userId);

            _memoryCache.Remove(urlCacheKey);
            _memoryCache.Remove(blobCacheKey);

            BaseSpecification <UserImageEntity> userImageSpecification = new BaseSpecification <UserImageEntity>();

            userImageSpecification.AddFilter(x => x.UserId == userId);

            UserImageEntity userImage = await _userImageRepository.SingleOrDefault(userImageSpecification);

            if (userImage == null)
            {
                UserImageEntity newUserImage = new UserImageEntity(
                    userId: userId,
                    blobImage: image,
                    fileName: uploadProfileImageRequest.File.FileName);

                bool addResult = await _userImageRepository.Add(newUserImage);

                if (!addResult)
                {
                    _logger.LogError($"Failed to add user image. UserId {userId}");
                    return(Result.Fail("failed_to_add_user_image", "Failed to add user image"));
                }

                return(Result.Ok());
            }

            userImage.BlobImage = image;
            userImage.FileName  = uploadProfileImageRequest.File.FileName;

            bool updateResult = await _userImageRepository.Update(userImage);

            if (!updateResult)
            {
                _logger.LogError($"Failed to update user image. UserId {userId}");
                return(Result.Fail("error", "Error"));
            }

            return(Result.Ok());
        }
        public async Task <Core.Models.Result.Result> UpdateProfileImage(string userId, UploadProfileImageRequest uploadProfileImageRequest)
        {
            if (uploadProfileImageRequest == null || uploadProfileImageRequest.File == null)
            {
                _logger.LogWarning($"No image. UserId {userId}");
                return(Result.Fail(PROFILE_IMAGE_NOT_FOUND).ToOldResult());
            }

            //TODO: changed how image format is validated
            string imageExtension = Path.GetExtension(uploadProfileImageRequest.File.FileName);

            if (!VALID_IMAGE_FORMATS.Contains(imageExtension.ToUpper()))
            {
                _logger.LogWarning($"Invalid image format. UserId {userId}, image extension {imageExtension}");
                return(Result.Fail(INVALID_PROFILE_IMAGE_FORMAT, VALID_IMAGE_FORMATS).ToOldResult());
            }

            if (uploadProfileImageRequest.File.Length > _identityUIOptions.MaxProfileImageSize)
            {
                _logger.LogWarning($"Image is to big. UserId {userId}, image size {uploadProfileImageRequest.File.Length}");
                return(Result.Fail(PROFILE_IMAGE_TOO_BIG, _identityUIOptions.MaxProfileImageSize / 1024).ToOldResult());
            }

            if (uploadProfileImageRequest.File.FileName.Length > 250)
            {
                _logger.LogWarning($"Image name is to long. Image name length {uploadProfileImageRequest.File.FileName.Length}");
                return(Result.Fail(PROFILE_IMAGE_NAME_TOO_LONG, 250).ToOldResult());
            }

            byte[] image;

            using (MemoryStream memoryStream = new MemoryStream())
            {
                await uploadProfileImageRequest.File.CopyToAsync(memoryStream);

                image = memoryStream.ToArray();
            }

            string blobCacheKey = string.Format(BLOBL_CACHE_KEY, userId);
            string urlCacheKey  = string.Format(URL_CACHE_KEY, userId);

            _memoryCache.Remove(blobCacheKey);
            _memoryCache.Remove(urlCacheKey);

            IBaseSpecification <UserImageEntity, UserImageEntity> getUserImageSpecification = SpecificationBuilder
                                                                                              .Create <UserImageEntity>()
                                                                                              .Where(x => x.UserId == userId)
                                                                                              .Build();

            UserImageEntity userImage = await _userImageDAO.SingleOrDefault(getUserImageSpecification);

            if (userImage == null)
            {
                UserImageEntity newUserImage = new UserImageEntity(
                    userId: userId,
                    blobImage: image,
                    fileName: uploadProfileImageRequest.File.FileName);

                bool addResult = await _userImageDAO.Add(newUserImage);

                if (!addResult)
                {
                    _logger.LogError($"Failed to add user image. UserId {userId}");
                    return(Result.Fail(FAILED_TO_ADD_PROFILE_IMAGE).ToOldResult());
                }

                return(Result.Ok().ToOldResult());
            }

            userImage.BlobImage = image;
            userImage.FileName  = uploadProfileImageRequest.File.FileName;

            bool updateResult = await _userImageDAO.Update(userImage);

            if (!updateResult)
            {
                _logger.LogError($"Failed to update user image. UserId {userId}");
                return(Result.Fail(FAILED_TO_UPDATE_PROFILE_IMAGE).ToOldResult());
            }

            return(Result.Ok().ToOldResult());
        }