using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
using ZB.MOM.WW.ScadaBridge.Commons.Types.InboundApi;
namespace ZB.MOM.WW.ScadaBridge.InboundAPI;
///
/// Builds the synchronous JSON-Schema $ref resolution seam the
/// InboundAPI RUNTIME validators ( /
/// ) consume, backed by the central shared-schema
/// library ().
///
///
/// Before this fix the runtime validators called the single-arg
/// InboundApiSchema.Parse(json) with NO resolver, so a method whose
/// parameter/return definition used a {"$ref":"lib:Name"} deployed fine
/// (deploy-time validation resolves it) but FAILED at every runtime invocation with
/// an opaque HTTP 400 — a deploy-passes/runtime-breaks defect. This helper mirrors how
/// the deploy path (FlatteningPipeline) pre-loads the library ONCE into an
/// in-memory name→JSON map and exposes a pure synchronous lookup as the seam, avoiding
/// sync-over-async inside the validators.
///
///
///
/// The pre-load is gated on : a definition
/// that uses no $ref at all skips the repository round-trip entirely and returns
/// null (no resolver), so a $ref-free method pays NO extra cost beyond
/// today's behavior.
///
///
internal static class SchemaRefResolver
{
///
/// Builds a lib:Name → schema-JSON resolution seam for the supplied
/// definitions, pre-loading the shared-schema library only when at least one of the
/// definitions actually contains a $ref.
///
///
/// The shared-schema repository, or null when none is registered (e.g. a bare
/// test-double provider) — then no resolver is produced and any $ref dangles.
///
/// The schema definition JSON strings to be validated (parameter and/or return).
/// Cancellation token for the library load.
///
/// A synchronous name → schema JSON? resolver, or null when no definition
/// uses a $ref (so the validators take their unchanged no-resolver path).
///
public static async Task?> BuildAsync(
ISharedSchemaRepository? repository,
IEnumerable definitions,
CancellationToken ct = default)
{
// Skip the library round-trip entirely unless some definition uses a $ref.
if (repository is null || !definitions.Any(InboundApiSchema.MightContainRef))
{
return null;
}
var library = await repository.ListAsync(ct);
var map = library.ToDictionary(s => s.Name, s => s.SchemaJson, StringComparer.Ordinal);
return name => map.GetValueOrDefault(name);
}
}