using PrivaPub.Infrastructure.Statistics; using System.Text.Json.Nodes; using static PrivaPub.Federation.Objects.ActivityJson; namespace PrivaPub.Federation.Objects { public sealed record ActivityShape(string Type, string ObjectType, string Audience) { public static ActivityShape Of(JsonNode activity) { var embedded = activity?["object"] as JsonObject; return new ActivityShape(Value(activity, "type"), Value(embedded, "type"), AudienceOf(activity)); } public static ActivityShape Of(string json) { try { return Of(JsonNode.Parse(json)); } catch (System.Text.Json.JsonException) { return new ActivityShape(default, default, default); } } static string AudienceOf(JsonNode activity) { var source = activity?["to"] != default || activity?["cc"] != default ? activity : activity?["object"] as JsonObject; var to = Addresses(source?["to"]); var cc = Addresses(source?["cc"]); if (to.Any(Addressing.IsPublic)) return Interactions.Public; if (cc.Any(Addressing.IsPublic)) return Interactions.Unlisted; return to.Count + cc.Count == 0 ? Interactions.None : Interactions.Private; } static List Addresses(JsonNode node) => node switch { JsonArray array => array.Select(Id).Where(id => id != default).ToList(), JsonNode single when Id(single) is { } id => new List { id }, _ => new List() }; } }