// This file is auto-generated by alef. DO NOT EDIT.
#nullable enable

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace {{ namespace }};
{% if doc -%}

/// <summary>
{% for line in doc_lines %}
/// {{ line }}
{% endfor %}
/// </summary>
{%- endif %}

/// <summary>
/// Transparent wrapper for an untagged Rust union (`#[serde(untagged)]`).
/// Holds the raw JSON shape so the Rust core can resolve the variant on the
/// way in. Use `Of(...)` / `FromJson(...)` to construct, and the `As*()`
/// probes to inspect on the way out.
/// </summary>
[JsonConverter(typeof({{ class_name }}JsonConverter))]
public sealed class {{ class_name }} : IEquatable<{{ class_name }}>
{
    public JsonElement Value { get; }

    public {{ class_name }}(JsonElement value)
    {
        // Clone the JsonElement into an owned document so the wrapper outlives
        // the JsonReader/JsonDocument that produced the element.
        Value = value.ValueKind == JsonValueKind.Undefined
            ? value
            : JsonDocument.Parse(value.GetRawText()).RootElement.Clone();
    }

    public static {{ class_name }} Of(string s)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(s));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} Of(IEnumerable<string> items)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(items));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} OfObject(object o)
    {
        using var doc = JsonDocument.Parse(JsonSerializer.Serialize(o));
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public static {{ class_name }} FromJson(string json)
    {
        using var doc = JsonDocument.Parse(json);
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public string? AsString() =>
        Value.ValueKind == JsonValueKind.String ? Value.GetString() : null;

    public List<string>? AsList()
    {
        if (Value.ValueKind != JsonValueKind.Array) return null;
        var result = new List<string>(Value.GetArrayLength());
        foreach (var element in Value.EnumerateArray())
        {
            result.Add(element.ToString());
        }
        return result;
    }

    public JsonElement? AsObject() =>
        Value.ValueKind == JsonValueKind.Object ? Value : null;
{% if emit_text %}
    /// <summary>
    /// Returns the plain-text display value of this content.
    /// <list type="bullet">
    ///   <item>If the value is a JSON string, it is returned verbatim.</item>
    ///   <item>If the value is a JSON array, the <c>"text"</c> field of every element
    ///     whose <c>"type"</c> equals <c>"text"</c> is concatenated in order;
    ///     non-text parts (images, audio, refusals, etc.) are skipped.</item>
    ///   <item>Otherwise (null, object, empty) returns <c>""</c>.</item>
    /// </list>
    /// </summary>
    public string Text()
    {
        if (Value.ValueKind == JsonValueKind.String)
            return Value.GetString() ?? string.Empty;
        if (Value.ValueKind == JsonValueKind.Array)
        {
            var sb = new System.Text.StringBuilder();
            foreach (var part in Value.EnumerateArray())
            {
                if (part.TryGetProperty("type", out var typeEl)
                    && typeEl.GetString() == "text"
                    && part.TryGetProperty("text", out var textEl))
                {
                    sb.Append(textEl.GetString() ?? string.Empty);
                }
            }
            return sb.ToString();
        }
        return string.Empty;
    }
{% endif %}
    public bool Equals({{ class_name }}? other) =>
        other is not null && Value.GetRawText() == other.Value.GetRawText();

    public override bool Equals(object? obj) => Equals(obj as {{ class_name }});

    public override int GetHashCode() => Value.GetRawText().GetHashCode();

    public override string ToString() => Value.GetRawText();
}

internal sealed class {{ class_name }}JsonConverter : JsonConverter<{{ class_name }}>
{
    public override {{ class_name }} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        return new {{ class_name }}(doc.RootElement.Clone());
    }

    public override void Write(Utf8JsonWriter writer, {{ class_name }} value, JsonSerializerOptions options)
    {
        value.Value.WriteTo(writer);
    }
}
