using System.Globalization; using System.Reflection; namespace CatalogLite; internal static class ExpirationGuard { private const string GeneratedMetadataKey = "CatalogLiteGeneratedExpirationDate"; private const string MetadataKey = "CatalogLiteExpirationDate"; public static bool IsExpired(out DateOnly? expirationDate) { expirationDate = TryReadExpirationDate(); return expirationDate is null || DateOnly.FromDateTime(DateTime.Now) > expirationDate.Value; } private static DateOnly? TryReadExpirationDate() { if (TryParseDate(BuildExpiration.ExpirationDate, out var generatedDate)) { return generatedDate; } var metadata = typeof(Program).Assembly.GetCustomAttributes(); var metadataValue = metadata.FirstOrDefault(attribute => string.Equals(attribute.Key, GeneratedMetadataKey, StringComparison.Ordinal))?.Value ?? metadata.FirstOrDefault(attribute => string.Equals(attribute.Key, MetadataKey, StringComparison.Ordinal))?.Value; return TryParseDate(metadataValue, out var metadataDate) ? metadataDate : null; } private static bool TryParseDate(string? value, out DateOnly date) { var trimmedValue = value?.Trim(); return DateOnly.TryParseExact(trimmedValue, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out date) || DateOnly.TryParse(trimmedValue, CultureInfo.CurrentCulture, DateTimeStyles.None, out date); } }