using System.Globalization;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization.Metadata;
namespace UAnalytics;
internal static class Request
{
internal static JsonNode Num(string parameter, double value, int? index = null)
{
if (double.IsFinite(value))
return JsonValue.Create(value);
var where = index is { } i ? $"{parameter}[{i}]" : parameter;
var body = new JsonObject
{
["error"] = $"{where}: expected a finite number, got {value.ToString(CultureInfo.InvariantCulture)}",
["code"] = "value_not_finite",
["index"] = index,
["parameter"] = parameter,
};
throw AnalyticsException.FromErrorBody(-3, body.ToJsonString());
}
internal static JsonNode? Num(string parameter, double? value)
=> value is { } v ? Num(parameter, v) : null;
internal static JsonArray Nums(string parameter, IReadOnlyList<double> values)
{
var array = new JsonArray();
for (var i = 0; i < values.Count; i++)
array.Add(Num(parameter, values[i], i));
return array;
}
internal static JsonArray Rows(string parameter, IReadOnlyList<IReadOnlyList<double>> rows)
{
var array = new JsonArray();
for (var r = 0; r < rows.Count; r++)
array.Add((JsonNode)Nums($"{parameter}[{r}]", rows[r]));
return array;
}
internal static JsonArray Rows(string parameter, IReadOnlyList<IReadOnlyList<IReadOnlyList<double>>> blocks)
{
var array = new JsonArray();
for (var b = 0; b < blocks.Count; b++)
array.Add((JsonNode)Rows($"{parameter}[{b}]", blocks[b]));
return array;
}
internal static JsonArray Counts(IReadOnlyList<ulong> values)
{
var array = new JsonArray();
foreach (var v in values)
array.Add((JsonNode)JsonValue.Create(v));
return array;
}
internal static JsonArray Counts(IReadOnlyList<IReadOnlyList<ulong>> rows)
{
var array = new JsonArray();
foreach (var row in rows)
array.Add((JsonNode)Counts(row));
return array;
}
internal static JsonArray Counts(IReadOnlyList<IReadOnlyList<long>> rows)
{
var array = new JsonArray();
foreach (var row in rows)
{
var inner = new JsonArray();
foreach (var v in row)
inner.Add((JsonNode)JsonValue.Create(v));
array.Add((JsonNode)inner);
}
return array;
}
internal static JsonNode Option<T>(T value, JsonTypeInfo<T> info)
=> JsonSerializer.SerializeToNode(value, info)
?? throw new InvalidOperationException($"{typeof(T).Name} has no JSON form.");
internal static JsonArray? Rules(IReadOnlyList<RunRule>? rules)
{
if (rules is null)
return null;
var array = new JsonArray();
foreach (var rule in rules)
array.Add(Option(rule, AnalyticsJson.Default.RunRule));
return array;
}
internal static JsonObject Body(params (string Key, JsonNode? Value)[] members)
{
var body = new JsonObject();
foreach (var (key, value) in members)
{
if (value is not null)
body[key] = value;
}
return body;
}
}