using System.Text;
using System.Text.Json;

namespace ZB.MOM.WW.ScadaBridge.CLI;

/// <summary>
/// Shared trigger-config JSON helpers for CLI paths that receive a raw
/// <c>--trigger-config</c> JSON blob and need to inject or strip the
/// <c>"analysisKind"</c> key based on <c>--trigger-kind</c>.
/// Used by <c>alarm update</c>, <c>script add</c>, and <c>script update</c>
/// (alarm add uses <see cref="AlarmTriggerConfigJson.Build"/> instead).
/// </summary>
internal static class TriggerConfigJson
{
    /// <summary>
    /// Copies every property from <paramref name="json"/> into a new object,
    /// adding or replacing <c>"analysisKind"</c> when
    /// <paramref name="analysisKind"/> is <c>"strict"</c> (case-insensitive),
    /// or omitting it for any other value (including <see langword="null"/>).
    /// Returns <see langword="null"/> when <paramref name="json"/> is
    /// <see langword="null"/> or empty, preserving the caller's null-means-no-config
    /// semantics.
    /// </summary>
    /// <param name="json">Raw trigger-config JSON object, or null.</param>
    /// <param name="analysisKind">
    /// Value of <c>--trigger-kind</c>: <c>"strict"</c> → write
    /// <c>"analysisKind":"Strict"</c>; anything else → omit the key.
    /// </param>
    /// <returns>
    /// The rewritten JSON string, or <see langword="null"/> when
    /// <paramref name="json"/> is null/empty.
    /// </returns>
    internal static string? InjectAnalysisKind(string? json, string? analysisKind)
    {
        if (string.IsNullOrWhiteSpace(json))
            return null;

        var isStrict = string.Equals(analysisKind?.Trim(), "Strict", StringComparison.OrdinalIgnoreCase);

        using var inputDoc = JsonDocument.Parse(json);
        using var stream = new MemoryStream();
        using (var writer = new Utf8JsonWriter(stream))
        {
            writer.WriteStartObject();

            // Copy all existing properties except "analysisKind" (we'll re-add it below if needed)
            foreach (var prop in inputDoc.RootElement.EnumerateObject())
            {
                if (!prop.NameEquals("analysisKind"))
                    prop.WriteTo(writer);
            }

            if (isStrict)
                writer.WriteString("analysisKind", "Strict");

            writer.WriteEndObject();
        }

        return Encoding.UTF8.GetString(stream.ToArray());
    }
}
