using System.Text.Json;
using System.Text.Json.Serialization;
using SQLInsight.Core.Instances;
namespace SQLInsight.Rules.Lifecycle;
public sealed record SupportLifecycle(SqlServerRelease Release, DateOnly? MainstreamEnd, DateOnly? ExtendedEnd);
///
/// Microsoft's support dates per SQL Server release. Shipped as data so it can be updated with the rule pack.
///
public sealed class SupportLifecycleCatalog
{
private const string ResourceName = "SQLInsight.Rules.support-lifecycle.json";
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter() },
};
private readonly Dictionary _entries;
public SupportLifecycleCatalog(IEnumerable entries)
{
ArgumentNullException.ThrowIfNull(entries);
_entries = entries.ToDictionary(e => e.Release);
}
public static SupportLifecycleCatalog LoadEmbedded()
{
using var stream = typeof(SupportLifecycleCatalog).Assembly.GetManifestResourceStream(ResourceName)
?? throw new InvalidOperationException($"Embedded resource '{ResourceName}' is missing.");
return From(JsonSerializer.Deserialize(stream, JsonOptions));
}
/// Reads the lifecycle section of a rule pack. Throws if it is malformed.
public static SupportLifecycleCatalog FromJson(JsonElement element) => From(element.Deserialize(JsonOptions));
private static SupportLifecycleCatalog From(CatalogDocument? document)
{
if (document?.Releases is not { Count: > 0 } releases)
{
throw new InvalidDataException("The support lifecycle catalog is empty.");
}
try
{
return new SupportLifecycleCatalog(releases);
}
catch (ArgumentException ex)
{
throw new InvalidDataException("The support lifecycle catalog is invalid: " + ex.Message, ex);
}
}
public SupportLifecycle? Find(SqlServerRelease release) => _entries.GetValueOrDefault(release);
private sealed record CatalogDocument(IReadOnlyList Releases);
}