using System;
using Svrnty.CQRS.Events.Abstractions.Schema;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using Svrnty.CQRS.Events.Abstractions.Models;
namespace Svrnty.CQRS.Events.Abstractions.Schema;
///
/// Registry for managing event schema versions and automatic upcasting.
///
///
///
/// The schema registry tracks event evolution over time, enabling:
/// - Automatic discovery of event versions
/// - Multi-hop upcasting (V1 → V2 → V3)
/// - Schema storage for external consumers
/// - Type-safe version transitions
///
///
/// Usage Pattern:
/// 1. Register each event version with the registry
/// 2. Specify upcast relationships (V2 upcasts from V1)
/// 3. Framework automatically upcasts old events when consuming
///
///
public interface ISchemaRegistry
{
///
/// Registers a schema for an event version.
///
/// The event type to register.
/// The version number for this schema.
/// The previous version type this can upcast from (null for version 1).
/// Optional JSON schema for external consumers.
/// Cancellation token.
/// The registered schema information.
///
///
/// Example:
///
/// // Register V1 (initial version)
/// await registry.RegisterSchemaAsync<UserCreatedEventV1>(1);
///
/// // Register V2 (adds Email property)
/// await registry.RegisterSchemaAsync<UserCreatedEventV2>(2, upcastFromType: typeof(UserCreatedEventV1));
///
///
///
Task RegisterSchemaAsync(
int version,
Type? upcastFromType = null,
string? jsonSchema = null,
CancellationToken cancellationToken = default)
where TEvent : ICorrelatedEvent;
///
/// Gets schema information for a specific event type and version.
///
/// The event type name.
/// The version number.
/// Cancellation token.
/// Schema information if found; otherwise null.
Task GetSchemaAsync(
string eventType,
int version,
CancellationToken cancellationToken = default);
///
/// Gets schema information for a CLR type.
///
/// The .NET type.
/// Cancellation token.
/// Schema information if found; otherwise null.
Task GetSchemaByTypeAsync(
Type clrType,
CancellationToken cancellationToken = default);
///
/// Gets the latest version number for an event type.
///
/// The event type name.
/// Cancellation token.
/// The latest version number, or null if no versions registered.
Task GetLatestVersionAsync(
string eventType,
CancellationToken cancellationToken = default);
///
/// Gets the complete schema history for an event type (all versions).
///
/// The event type name.
/// Cancellation token.
/// List of schema information ordered by version ascending.
Task> GetSchemaHistoryAsync(
string eventType,
CancellationToken cancellationToken = default);
///
/// Upcasts an event from its current version to the latest version.
///
/// The event to upcast.
/// The target version (null = latest version).
/// Cancellation token.
/// The upcast event at the target version.
///
///
/// Performs multi-hop upcasting if necessary. For example:
/// UserCreatedEventV1 → UserCreatedEventV2 → UserCreatedEventV3
///
///
/// Each hop is performed by:
/// 1. Looking for a static UpcastFrom method on the target type
/// 2. Looking for a registered IEventUpcaster implementation
/// 3. Throwing if no upcaster is found
///
///
Task UpcastAsync(
ICorrelatedEvent @event,
int? targetVersion = null,
CancellationToken cancellationToken = default);
///
/// Determines if an event needs upcasting.
///
/// The event to check.
/// The target version (null = latest version).
/// Cancellation token.
/// True if the event needs upcasting; otherwise false.
Task NeedsUpcastingAsync(
ICorrelatedEvent @event,
int? targetVersion = null,
CancellationToken cancellationToken = default);
}