using SafeNSound.Sdk; namespace SafeNSound.FakeUser; public class UserStore(SafeNSoundAuthentication authService, SafeNSoundConfiguration config) : IHostedService { public List Admins { get; } = Enumerable.Range(0, 1).Select(_ => new ClientContainer()).ToList(); public List Monitors { get; } = Enumerable.Range(0, 5).Select(_ => new ClientContainer()).ToList(); public List Users { get; } = Enumerable.Range(0, 15).Select(_ => new ClientContainer()).ToList(); public List AllUsers => [.. Users, .. Monitors, .. Admins]; public ClientContainer GetRandomUser() { ClientContainer user; do { user = Users[new Random().Next(Users.Count)]; } while (user.Client == null); return user; } public ClientContainer GetRandomMonitor() { ClientContainer user; do { user = Monitors[new Random().Next(Monitors.Count)]; } while (user.Client == null); return user; } public ClientContainer GetRandomAdmin() { ClientContainer user; do { user = Admins[new Random().Next(Admins.Count)]; } while (user.Client == null); return user; } public ClientContainer GetRandomUserOfAnyType() { ClientContainer user; do { user = AllUsers[new Random().Next(AllUsers.Count)]; } while (user.Client == null); return user; } public async Task StartAsync(CancellationToken cancellationToken) { Admins.ForEach(x => x.Auth.UserType = "admin"); Monitors.ForEach(x => x.Auth.UserType = "monitor"); var ss = new SemaphoreSlim(256, 256); var tasks = ((ClientContainer[]) [..Users, ..Monitors, ..Admins]).Select(async container => { await ss.WaitAsync(); await authService.Register(container.Auth); container.Client = new SafeNSoundClient(config, (await authService.Login(container.Auth)).AccessToken); container.WhoAmI = await container.Client.WhoAmI(); await container.Client.UpdateDevice(container.WhoAmI.DeviceId, new() { Name = "FakeUser-" + container.Auth.Username, }); if (container.Auth.UserType == "admin") { await container.Client.MonitorAllUsers(); } ss.Release(); }).ToList(); await Task.WhenAll(tasks); var users = Users.ToArray(); tasks = Monitors.Select(async container => { var items = Random.Shared.GetItems(users, Users.Count / Monitors.Count).DistinctBy(x=>x.WhoAmI!.UserId); foreach (var user in items) { await container.Client!.AddAssignedUser(user.WhoAmI!.UserId); } }).ToList(); await Task.WhenAll(tasks); } public async Task StopAsync(CancellationToken cancellationToken) { await Task.WhenAll(Users.Select(Cleanup).ToList()); await Task.WhenAll(Monitors.Select(Cleanup).ToList()); await Task.WhenAll(Admins.Select(Cleanup).ToList()); } private async Task Cleanup(ClientContainer container) { if (container.Client == null) return; try { _ = await container.Client.GetDevices(); if(Random.Shared.Next(100)>50) await container.Client.DeleteDevice(container.WhoAmI!.DeviceId); else await container.Client.LogOut(); await container.Client.DeleteAccount(container.Auth); } catch { Console.WriteLine("Failed to delete account for user: " + container.Auth.Username); } } public class ClientContainer { public RegisterDto Auth { get; set; } = new() { Email = $"{Guid.NewGuid()}@example.com", Username = $"user-{Guid.NewGuid()}", Password = Guid.NewGuid().ToString(), UserType = "user" }; public SafeNSoundClient? Client { get; set; } public WhoAmI? WhoAmI { get; set; } } }