/// <summary>
        /// Records a user comment on a video.
        /// </summary>
        public async Task CommentOnVideo(CommentOnVideo comment)
        {
            // Use a client side timestamp for the writes that we can include when we publish the event
            var timestamp = DateTimeOffset.UtcNow;

            PreparedStatement[] preparedStatements = await _statementCache.NoContext.GetOrAddAllAsync(
                "INSERT INTO comments_by_video (videoid, commentid, userid, comment) VALUES (?, ?, ?, ?) USING TIMESTAMP ?",
                "INSERT INTO comments_by_user (userid, commentid, videoid, comment) VALUES (?, ?, ?, ?) USING TIMESTAMP ?");

            // Use a batch to insert into all tables
            var batch = new BatchStatement();

            // INSERT INTO comments_by_video
            batch.Add(preparedStatements[0].Bind(comment.VideoId, comment.CommentId, comment.UserId, comment.Comment,
                                                 timestamp.ToMicrosecondsSinceEpoch()));

            // INSERT INTO comments_by_user
            batch.Add(preparedStatements[1].Bind(comment.UserId, comment.CommentId, comment.VideoId, comment.Comment,
                                                 timestamp.ToMicrosecondsSinceEpoch()));

            await _session.ExecuteAsync(batch).ConfigureAwait(false);

            // Tell the world about the comment
            await _bus.Publish(new UserCommentedOnVideo
            {
                UserId = comment.UserId,
                VideoId = comment.VideoId,
                CommentId = comment.CommentId,
                Timestamp = timestamp
            }).ConfigureAwait(false);
        }
        public async Task<JsonNetResult> Add(AddCommentViewModel model)
        {
            // Shouldn't throw because of the Authorize attribute
            Guid userId = User.GetCurrentUserId().Value;

            var commentTimestamp = DateTimeOffset.UtcNow;

            // Add the new comment
            var commentOnVideo = new CommentOnVideo
            {
                UserId = userId,
                VideoId = model.VideoId,
                CommentId = TimeUuid.NewId(commentTimestamp),
                Comment = model.Comment
            };

            await _comments.CommentOnVideo(commentOnVideo);

            // Lookup the current user's information to include in the return data
            UserProfile userInfo = await _userManagement.GetUserProfile(userId);

            return JsonSuccess(new VideoCommentViewModel
            {
                CommentId = commentOnVideo.CommentId,
                Comment = commentOnVideo.Comment,
                CommentTimestamp = commentTimestamp,
                UserProfileUrl = Url.Action("Info", "Account", new { userId }),
                UserFirstName = userInfo.FirstName,
                UserLastName = userInfo.LastName,
                UserGravatarImageUrl = GravatarHasher.GetImageUrlForEmailAddress(userInfo.EmailAddress)
            });
        }