using Microsoft.Extensions.Logging; using System.Application.Entities; using System.Application.Models; using System.Application.Repositories; using System.Diagnostics; using System.Security; using System.Threading.Tasks; using static System.Application.KeyConstants; namespace System.Application.Services.Implementation { /// public class UserManager : IUserManager { protected const string TAG = "UserManager"; protected readonly IStorage storage; protected readonly ILogger logger; protected readonly IUserRepository userRepository; protected readonly ISecurityService security; public UserManager( ILoggerFactory loggerFactory, IStorage storage, IUserRepository userRepository, ISecurityService security) { logger = loggerFactory.CreateLogger(TAG); this.storage = storage; this.userRepository = userRepository; this.security = security; } protected bool isAnonymous; protected CurrentUser? currentUser; //protected UserInfoDTO? currentUserInfo; protected CurrentUser? CurrentUser { set { currentUser = value; isAnonymous = value == null; } } [Conditional("DEBUG")] void PrintCurrentUser(string name) { logger.LogInformation( $"{name}: {currentUser?.ToStringHideMiddleFour()}"); } protected async ValueTask GetCurrentUserAsync(bool clone) { if (currentUser == null && !isAnonymous) { try { CurrentUser = await storage.GetAsync(KEY_CURRENT_LOGIN_USER); } catch (Exception e) { logger.LogError(e, nameof(GetCurrentUserAsync)); } PrintCurrentUser(nameof(GetCurrentUserAsync)); } return clone ? currentUser?.Clone() : currentUser; } public CurrentUser? GetCurrentUser() { var hasCurrentUser = currentUser != null; #if DEBUG var read_cache = Random2.Next(100) % 2 == 0; hasCurrentUser = read_cache && hasCurrentUser; #endif CurrentUser? result; if (hasCurrentUser) { result = currentUser?.Clone(); } else { Func> func = GetCurrentUserAsync; result = func.RunSync(); } #if DEBUG logger.LogDebug("read_cache: {0}, PhoneNumber: {1}", read_cache, result?.ToStringHideMiddleFour()); #endif return result; } public ValueTask GetCurrentUserAsync() { return GetCurrentUserAsync(true); } public async Task SetCurrentUserAsync(CurrentUser? value) { await storage.SetAsync(KEY_CURRENT_LOGIN_USER, currentUser); CurrentUser = value; PrintCurrentUser("SetCurrentUser"); } //public async ValueTask GetCurrentUserInfoAsync() //{ // if (currentUserInfo == null && !isAnonymous) // { // var cUser = await GetCurrentUserAsync(); // if (cUser != null) // { // currentUserInfo = await GetUserInfoByIdAsync(cUser.UserId); // } // } // return currentUserInfo; //} //public async Task SetCurrentUserInfoAsync(UserInfoDTO value, bool updateToDataBase) //{ // currentUserInfo = value; // if (updateToDataBase) // { // await InsertOrUpdateAsync(value); // } //} public async ValueTask GetAuthTokenAsync() { var value = await GetCurrentUserAsync(false); return value?.AuthToken; } public async Task SignOutAsync() { PrintCurrentUser("SignOut"); //currentUserInfo = default; await SetCurrentUserAsync(null); } ValueTask GetUserTableByIdAsync(Guid userId) { return userRepository.FindAsync(userId); } TUserDTO? GetUserByTable(User? user, Func binding) where TUserDTO : IUserDTO { if (user == null) return default; var value = binding.Invoke(user); return value; } TUserDTO? BindingUser(User user) where TUserDTO : IUserDTO, new() { var value = new TUserDTO { Id = user.Id, NickName = security.D(user.NickName), Avatar = user.Avatar, }; return value; } public async Task GetUserByIdAsync(Guid userId) { var user = await GetUserTableByIdAsync(userId); var value = GetUserByTable(user, BindingUser); return value; } //bool VerifyUserInfo(User user, UserInfoDTO userInfo) //{ // if (user.Id != userInfo.Id) // { // logger.LogError("VerifyUserInfo Fail(Id)."); // return false; // } // if (security.D(user.NickName) != userInfo.NickName) // { // logger.LogError("VerifyUserInfo Fail(NickName)."); // return false; // } // if (user.Avatar != userInfo.Avatar) // { // logger.LogError("VerifyUserInfo Fail(Avatar)."); // return false; // } // return true; //} //UserInfoDTO? BindingUserInfo(User user) //{ // if (user.UserInfo != null) // { // try // { // var userInfoBytes = security.DB(user.UserInfo); // if (userInfoBytes != null) // { // var value = Serializable.DMP(userInfoBytes); // if (value != null) // { // var v = VerifyUserInfo(user, value); // if (v) // { // return value; // } // } // } // } // catch (Exception e) // { // logger.LogError(e, "BindingUserInfo Serializable & Verify Fail."); // } // } // return BindingUser(user); //} //public async Task GetUserInfoByIdAsync(Guid userId) //{ // var user = await GetUserTableByIdAsync(userId); // return GetUserByTable(user, BindingUserInfo); //} public async Task InsertOrUpdateAsync(IUserDTO user) { var userTable = new User { Id = user.Id, NickName = security.E(user.NickName), Avatar = user.Avatar, }; //if (user is UserInfoDTO userInfo) //{ // userTable.UserInfo = Serializable.SMP(userInfo); // userTable.UserInfo = security.EB(userTable.UserInfo); //} //else //{ // var userTable2 = await GetUserTableByIdAsync(user.Id); // if (userTable2?.UserInfo != null) // { // userTable.UserInfo = userTable2.UserInfo; // } //} (var rowCount, var result) = await userRepository.InsertOrUpdateAsync(userTable); PrintInsertOrUpdateResult(user, rowCount, result); } [Conditional("DEBUG")] void PrintInsertOrUpdateResult(IUserDTO user, int rowCount, DbRowExecResult result) { logger.LogInformation( $"User.InsertOrUpdate " + $"rowCount: {rowCount}, " + $"result: {result}, " + $"user: [{user.NickName}-{user.Id}]"); } } }