using System.Collections.Immutable;
using System.Linq;
using System.Text.Json.Serialization;
namespace StellaOps.Concelier.Models;
/// 
/// Describes the origin of a canonical field and how/when it was captured.
/// 
public sealed record AdvisoryProvenance
{
    public static AdvisoryProvenance Empty { get; } = new("unknown", "unspecified", string.Empty, DateTimeOffset.UnixEpoch);
    [JsonConstructor]
    public AdvisoryProvenance(
        string source,
        string kind,
        string value,
        string? decisionReason,
        DateTimeOffset recordedAt,
        ImmutableArray fieldMask)
        : this(source, kind, value, recordedAt, fieldMask.IsDefault ? null : fieldMask.AsEnumerable(), decisionReason)
    {
    }
    public AdvisoryProvenance(
        string source,
        string kind,
        string value,
        DateTimeOffset recordedAt,
        IEnumerable? fieldMask = null,
        string? decisionReason = null)
    {
        Source = Validation.EnsureNotNullOrWhiteSpace(source, nameof(source));
        Kind = Validation.EnsureNotNullOrWhiteSpace(kind, nameof(kind));
        Value = Validation.TrimToNull(value);
        DecisionReason = Validation.TrimToNull(decisionReason);
        RecordedAt = recordedAt.ToUniversalTime();
        FieldMask = NormalizeFieldMask(fieldMask);
    }
    public string Source { get; }
    public string Kind { get; }
    public string? Value { get; }
    public string? DecisionReason { get; }
    public DateTimeOffset RecordedAt { get; }
    public ImmutableArray FieldMask { get; }
    private static ImmutableArray NormalizeFieldMask(IEnumerable? fieldMask)
    {
        if (fieldMask is null)
        {
            return ImmutableArray.Empty;
        }
        var buffer = fieldMask
            .Where(static value => !string.IsNullOrWhiteSpace(value))
            .Select(static value => value.Trim().ToLowerInvariant())
            .Distinct(StringComparer.Ordinal)
            .OrderBy(static value => value, StringComparer.Ordinal)
            .ToImmutableArray();
        return buffer.IsDefault ? ImmutableArray.Empty : buffer;
    }
}