using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using static Timeline.Resources.Services.UserDetailService;
namespace Timeline.Services
{
public interface IUserDetailService
{
///
/// Get the nickname of the user with given username.
/// If the user does not set a nickname, the username is returned as the nickname.
///
/// The username of the user to get nickname of.
/// The nickname of the user.
/// Thrown when is null.
/// Thrown when is of bad format.
/// Thrown when the user does not exist.
Task GetNickname(string username);
///
/// Set the nickname of the user with given username.
///
/// The username of the user to set nickname of.
/// The nickname. Pass null to unset.
/// Thrown when is null.
/// Thrown when is not null but its length is bigger than 10.
/// Thrown when is of bad format.
/// Thrown when the user does not exist.
Task SetNickname(string username, string? nickname);
}
public class UserDetailService : IUserDetailService
{
private readonly DatabaseContext _database;
private readonly ILogger _logger;
public UserDetailService(DatabaseContext database, ILogger logger)
{
_database = database;
_logger = logger;
}
public async Task GetNickname(string username)
{
var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username);
var nickname = _database.UserDetails.Where(d => d.UserId == userId).Select(d => new { d.Nickname }).SingleOrDefault()?.Nickname;
return nickname ?? username;
}
public async Task SetNickname(string username, string? nickname)
{
if (nickname != null && nickname.Length > 10)
{
throw new ArgumentException(ExceptionNicknameTooLong, nameof(nickname));
}
var userId = await DatabaseExtensions.CheckAndGetUser(_database.Users, username);
var userDetail = _database.UserDetails.Where(d => d.UserId == userId).SingleOrDefault();
if (nickname == null)
{
if (userDetail == null || userDetail.Nickname == null)
{
return;
}
else
{
userDetail.Nickname = null;
await _database.SaveChangesAsync();
_logger.LogInformation(LogEntityNicknameSetToNull, userId);
}
}
else
{
var create = userDetail == null;
if (create)
{
userDetail = new UserDetailEntity
{
UserId = userId
};
}
userDetail!.Nickname = nickname;
if (create)
{
_database.UserDetails.Add(userDetail);
}
await _database.SaveChangesAsync();
if (create)
{
_logger.LogInformation(LogEntityNicknameCreate, userId, nickname);
}
else
{
_logger.LogInformation(LogEntityNicknameSetNotNull, userId, nickname);
}
}
}
}
}