using DodoSSH.Contracts;

namespace DodoSSH.Api.Setup;

/// <summary>Brings the host's JSON handling into line with the shared contract.</summary>
internal static class Json
{
    /// <summary>
    /// Applies <see cref="DodoSshJsonContext"/>'s settings to the host's serialiser.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Not optional, and not a performance tweak. Without it the framework's web defaults apply: camelCase
    /// property names — which happen to match — but enums as <em>numbers</em>, and no rejection of unmapped
    /// members. Every request DTO carrying an enum then fails to bind against a client that writes the
    /// specified string form, which is the entire sync surface. The failure is a 400 naming only the
    /// parameter, and it is invisible to any test that posts with its own default options rather than the
    /// contract's.
    /// </para>
    /// <para>
    /// Found by running the real client against the real server for the first time. Every test until then
    /// serialised its requests with <c>PostAsJsonAsync</c>'s defaults, so both sides agreed on integers and
    /// nothing disagreed with anything.
    /// </para>
    /// <para>
    /// FastEndpoints does not use this <see cref="System.Text.Json.JsonSerializerOptions"/> instance. It
    /// copies from it, once, while the pipeline is being built. That copy is undocumented and process-wide,
    /// so <c>Setup/EndpointRegistration.cs</c> applies the same settings to it explicitly rather than
    /// trusting it — which is the lesson of the paragraph above, applied to the mechanism that replaced it.
    /// </para>
    /// </remarks>
    internal static IServiceCollection AddDodoJson(this IServiceCollection services) =>
        services.ConfigureHttpJsonOptions(options => DodoSshJsonContext.ApplyTo(options.SerializerOptions));
}
