namespace AyCode.Core.Serializers.Binaries;

/// <summary>
/// Delegate used to decide whether a property should be serialized.
/// </summary>
public delegate bool BinaryPropertyFilter(in BinaryPropertyFilterContext context);

/// <summary>
/// Provides property metadata and lazy value access for property filter evaluations.
/// </summary>
public readonly struct BinaryPropertyFilterContext
{
    private readonly object? _instance;
    private readonly Func<object, object?>? _valueGetter;

    public BinaryPropertyFilterContext(object? instance, Type declaringType, string propertyName, Type propertyType, Func<object, object?>? valueGetter)
    {
        _instance = instance;
        DeclaringType = declaringType;
        PropertyName = propertyName;
        PropertyType = propertyType;
        _valueGetter = valueGetter;
    }

    /// <summary>
    /// Gets the declaring type of the property.
    /// </summary>
    public Type DeclaringType { get; }

    /// <summary>
    /// Gets the property name.
    /// </summary>
    public string PropertyName { get; }

    /// <summary>
    /// Gets the property type.
    /// </summary>
    public Type PropertyType { get; }

    /// <summary>
    /// Gets the instance being serialized when available. Null during metadata registration.
    /// </summary>
    public object? Instance => _instance;

    /// <summary>
    /// Indicates whether the filter is invoked during metadata registration (when no instance is available).
    /// </summary>
    public bool IsMetadataPhase => _instance is null;

    /// <summary>
    /// Lazily obtains the current property value. Returns null when invoked during metadata registration.
    /// </summary>
    public object? GetValue()
    {
        if (_instance == null || _valueGetter == null)
            return null;

        return _valueGetter(_instance);
    }
}