using FastEndpoints; using SpaceGame.Api.Auth.Runtime; using SpaceGame.Api.Auth.Simulation; using SpaceGame.Api.PlayerFaction.Simulation; namespace SpaceGame.Api.PlayerFaction.Api; public sealed class GetPlayerIdentitiesHandler(IAuthRepository authRepository, IPlayerStateStore playerStateStore) : EndpointWithoutRequest> { public override void Configure() { Get("/api/player-faction/identities"); Policies(AuthPolicyNames.GmAccess); } public override async Task HandleAsync(CancellationToken cancellationToken) { var users = await authRepository.ListUsersAsync(cancellationToken); var playerFactionsById = playerStateStore.GetPlayerFactions() .ToDictionary(player => player.Id, StringComparer.Ordinal); var responses = new List(users.Count + playerFactionsById.Count); var seenIds = new HashSet(StringComparer.Ordinal); foreach (var user in users) { var userId = user.Id.ToString("N"); playerFactionsById.TryGetValue(userId, out var playerFaction); responses.Add(new PlayerIdentitySummaryResponse( userId, user.Email, user.Roles, playerFaction is not null, playerFaction?.Id, playerFaction?.Label, playerFaction?.SovereignFactionId)); seenIds.Add(userId); } foreach (var playerFaction in playerStateStore.GetPlayerFactions()) { if (!seenIds.Add(playerFaction.Id)) { continue; } responses.Add(new PlayerIdentitySummaryResponse( playerFaction.Id, $"{playerFaction.Id}@unknown", Array.Empty(), true, playerFaction.Id, playerFaction.Label, playerFaction.SovereignFactionId)); } await SendOkAsync( responses .OrderBy(response => response.Email, StringComparer.OrdinalIgnoreCase) .ThenBy(response => response.UserId, StringComparer.Ordinal) .ToList(), cancellationToken); } } public sealed record PlayerIdentitySummaryResponse( string UserId, string Email, IReadOnlyList Roles, bool HasPlayerFaction, string? PlayerFactionId, string? PlayerFactionLabel, string? SovereignFactionId);