aboutsummaryrefslogtreecommitdiff
path: root/Timeline/Services/UserDetailService.cs
blob: 5e0494351ce8dae676be67557434720e7b6bffea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;

namespace Timeline.Services
{
    public interface IUserDetailService
    {
        /// <summary>
        /// Get the nickname of user.
        /// </summary>
        /// <param name="username">The username to get nickname of.</param>
        /// <returns>The user's nickname. Null if not set.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="username"/> is null or empty.</exception>
        /// <exception cref="UserNotExistException">Thrown if user doesn't exist.</exception>
        Task<string> GetUserNickname(string username);

        /// <summary>
        /// Get the detail of user.
        /// </summary>
        /// <param name="username">The username to get user detail of.</param>
        /// <returns>The user detail.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="username"/> is null or empty.</exception>
        /// <exception cref="UserNotExistException">Thrown if user doesn't exist.</exception>
        Task<UserDetail> GetUserDetail(string username);

        /// <summary>
        /// Update the detail of user. This function does not do data check.
        /// </summary>
        /// <param name="username">The username to get user detail of.</param>
        /// <param name="detail">The detail to update. Can't be null. Any null member means not set.</param>
        /// <exception cref="ArgumentException">Thrown if <paramref name="username"/> is null or empty or <paramref name="detail"/> is null.</exception>
        /// <exception cref="UserNotExistException">Thrown if user doesn't exist.</exception>
        Task UpdateUserDetail(string username, UserDetail detail);
    }

    public class UserDetailService : IUserDetailService
    {
        private readonly ILogger<UserDetailService> _logger;

        private readonly DatabaseContext _databaseContext;

        public UserDetailService(ILogger<UserDetailService> logger, DatabaseContext databaseContext)
        {
            _logger = logger;
            _databaseContext = databaseContext;
        }

        private async Task<UserDetailEntity> CreateEntity(long userId)
        {
            var entity = new UserDetailEntity()
            {
                UserId = userId
            };
            _databaseContext.UserDetails.Add(entity);
            await _databaseContext.SaveChangesAsync();
            _logger.LogInformation("An entity is created in user_details.");
            return entity;
        }

        // Check the existence of user detail entry
        private async Task<UserDetailEntity> CheckAndInit(long userId)
        {
            var detail = await _databaseContext.UserDetails.Where(e => e.UserId == userId).SingleOrDefaultAsync();
            if (detail == null)
            {
                detail = await CreateEntity(userId);
            }
            return detail;
        }

        public async Task<string> GetUserNickname(string username)
        {
            var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
            var detail = await _databaseContext.UserDetails.Where(e => e.UserId == userId).Select(e => new { e.Nickname }).SingleOrDefaultAsync();
            if (detail == null)
            {
                var entity = await CreateEntity(userId);
                return null;
            }
            else
            {
                var nickname = detail.Nickname;
                return string.IsNullOrEmpty(nickname) ? null : nickname;
            }
        }

        public async Task<UserDetail> GetUserDetail(string username)
        {
            var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
            var detailEntity = await CheckAndInit(userId);
            return UserDetail.From(detailEntity);
        }

        public async Task UpdateUserDetail(string username, UserDetail detail)
        {
            if (detail == null)
                throw new ArgumentNullException(nameof(detail));

            var userId = await DatabaseExtensions.CheckAndGetUser(_databaseContext.Users, username);
            var detailEntity = await CheckAndInit(userId);

            if (detail.Nickname != null)
                detailEntity.Nickname = detail.Nickname;

            if (detail.QQ != null)
                detailEntity.QQ = detail.QQ;

            if (detail.Email != null)
                detailEntity.Email = detail.Email;

            if (detail.PhoneNumber != null)
                detailEntity.PhoneNumber = detail.PhoneNumber;

            if (detail.Description != null)
                detailEntity.Description = detail.Description;

            await _databaseContext.SaveChangesAsync();
            _logger.LogInformation("An entity is updated in user_details.");
        }
    }

    public static class UserDetailServiceCollectionExtensions
    {
        public static void AddUserDetailService(this IServiceCollection services)
        {
            services.AddScoped<IUserDetailService, UserDetailService>();
        }
    }
}