using System.Text.Json;
using System.Text.Json.Serialization;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace ZB.MOM.WW.OtOpcUa.Driver.Calculation;

/// <summary>
///     Test-connect probe for the <c>Calculation</c> pseudo-driver. There is no backend to connect to —
///     the driver computes tags from other tags' values — so the probe just confirms the driver config
///     parses (mini-design §7). Per-script compile verification belongs to the editor diagnostics + the
///     tag editor's inline panel, not the probe (which receives only the driver config). Never throws;
///     returns Ok with negligible latency.
/// </summary>
public sealed class CalculationDriverProbe : IDriverProbe
{
    private static readonly JsonSerializerOptions Opts = new()
    {
        PropertyNameCaseInsensitive = true,
        UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
        Converters = { new JsonStringEnumConverter() },
    };

    /// <inheritdoc />
    public string DriverType => CalculationDriverFactoryExtensions.DriverTypeName;

    /// <inheritdoc />
    public Task<DriverProbeResult> ProbeAsync(string configJson, TimeSpan timeout, CancellationToken ct)
    {
        if (string.IsNullOrWhiteSpace(configJson))
            return Task.FromResult(new DriverProbeResult(false, "Config JSON is empty.", null));

        try
        {
            // Parse-only: a Calculation driver's config is well-formed as long as it deserialises to an
            // object (the RawTags array is optional — a driver with no calc tags is still valid).
            _ = JsonSerializer.Deserialize<CalculationDriverFactoryExtensions.CalculationDriverConfigDto>(configJson, Opts);
        }
        catch (Exception ex)
        {
            return Task.FromResult(new DriverProbeResult(false, $"Config JSON is invalid: {ex.Message}", null));
        }

        return Task.FromResult(new DriverProbeResult(true, null, TimeSpan.Zero));
    }
}
