using AutoMapper; using RecNet.Application.Common.Interfaces; using RecNet.Domain.GameVersions; using RecNet.Domain.Profiles; using ProfileEntity = RecNet.Domain.Profiles.Profile; namespace RecNet.Application.Profiles; public class ProfileService( IEnumerable validators, IGameVersionRepository gameVersionRepository, IProfileRepository profileRepository, IConfigService configService, NameGenerator nameGenerator, ITokenService tokenService, IMapper mapper) : IProfileService { public async Task GetProfileAsync(Guid profileId, CancellationToken ct = default) { var profile = await profileRepository.GetByIdAsync(profileId, ct); return profile is null ? null : mapper.Map(profile); } public async Task> GetProfilesAsync( List profileIds, CancellationToken ct = default) { var profiles = await profileRepository.GetByIdsAsync(profileIds, ct); return mapper.Map>(profiles); } public async Task LoginAsync( LoginProfileCommand command, CancellationToken ct = default) { // 1. Validate Game Version if (string.IsNullOrWhiteSpace(command.AppVersion)) return LoginProfileResult.Fail("App version is required."); var isValidGameVersion = await gameVersionRepository.IsValidAsync(command.AppVersion, ct); if (!isValidGameVersion) return LoginProfileResult.Fail("Invalid app version."); // 2. Validate Platform Authentication var validator = validators.FirstOrDefault(x => x.PlatformType == command.PlatformType); if (validator is null) return LoginProfileResult.Fail("Invalid platform type"); var ignoreAuthValidation = await configService.GetAsync("Profiles:IgnoreAuthValidation", true, ct); var auth = await validator.ValidateAsync( command.PlatformAuthentication, command.PlatformId, ct); if (!auth.Succeeded && !ignoreAuthValidation) return LoginProfileResult.Fail($"Platform Auth Failed: {auth.Message}"); // 3. Get or Create Profile var profile = await profileRepository.GetByPlatform( command.PlatformType, command.PlatformId, ct); if (profile is null) { var name = await nameGenerator.GenerateAsync(ct); profile = ProfileEntity.Create( name, command.PlatformType, command.PlatformId); await profileRepository.AddAsync(profile, ct); } if (profile.IsBanned) return LoginProfileResult.Fail("Profile is banned"); profile.RecordSuccessfulLogin(command.DeviceId, auth.Name); await profileRepository.SaveChangesAsync(ct); var token = tokenService.GenerateProfileToken(profile); return LoginProfileResult.Success( profile: mapper.Map(profile), accessToken: token.AccessToken, expiresIn: token.ExpiresIn ); } }