namespace SafeNSound.FakeUser; public class UserService(ILogger logger, UserStore userStore) : IHostedService { private Task _alarmTask, _spendBudgetTask; private readonly CancellationTokenSource _cts = new(); public async Task StartAsync(CancellationToken cancellationToken) { _alarmTask = ManageAlarms(_cts.Token); _spendBudgetTask = AssignBudget(_cts.Token); } private static readonly string[] validReasons = ["fall", "toilet"]; private async Task ManageAlarms(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var user = userStore.GetRandomUser(); var currentAlarm = await user.Client!.GetAlarm(); if (currentAlarm is null) { await user.Client!.SetAlarm(new Sdk.AlarmDto { Reason = Random.Shared.GetItems(validReasons, 1).First() }); } else { await user.Client!.DeleteAlarm(); } } catch (Exception ex) { logger.LogError(ex, "Error setting/deleting alarm"); } await Task.Delay(TimeSpan.FromMilliseconds(250), cancellationToken); } } private async Task AssignBudget(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { try { var user = userStore.GetRandomUser(); var budget = await user.Client!.GetBudget(); await user.Client!.SpendBudget(new() { Amount = Math.Min(budget.Amount, Random.Shared.NextDouble()), Reason = "Random budget spending", Venue = "The Store" }); await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); } catch (Exception ex) { logger.LogError(ex, "Error spending budget"); } } } public async Task StopAsync(CancellationToken cancellationToken) { await _cts.CancelAsync(); await _alarmTask; await _spendBudgetTask; } }