using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace StellaOps.Vexer.Storage.Mongo;

/// <summary>
/// Configuration controlling Mongo-backed storage for Vexer repositories.
/// </summary>
public sealed class VexMongoStorageOptions : IValidatableObject
{
    private const int DefaultInlineThreshold = 256 * 1024;
    private static readonly TimeSpan DefaultCacheTtl = TimeSpan.FromHours(12);

    /// <summary>
    /// Name of the GridFS bucket used for raw VEX payloads that exceed <see cref="GridFsInlineThresholdBytes"/>.
    /// </summary>
    public string RawBucketName { get; set; } = "vex.raw";

    /// <summary>
    /// Inline raw document payloads smaller than this threshold; larger payloads are stored in GridFS.
    /// </summary>
    public int GridFsInlineThresholdBytes { get; set; } = DefaultInlineThreshold;

    /// <summary>
    /// Default TTL applied to export cache entries (absolute expiration).
    /// </summary>
    public TimeSpan ExportCacheTtl { get; set; } = DefaultCacheTtl;

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (string.IsNullOrWhiteSpace(RawBucketName))
        {
            yield return new ValidationResult("Raw bucket name must be provided.", new[] { nameof(RawBucketName) });
        }

        if (GridFsInlineThresholdBytes < 0)
        {
            yield return new ValidationResult("GridFS inline threshold must be non-negative.", new[] { nameof(GridFsInlineThresholdBytes) });
        }

        if (ExportCacheTtl <= TimeSpan.Zero)
        {
            yield return new ValidationResult("Export cache TTL must be greater than zero.", new[] { nameof(ExportCacheTtl) });
        }
    }
}
