using ZB.MOM.WW.ScadaBridge.Commons.Entities.ExternalSystems;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.InboundApi; // ApiMethod
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Notifications;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Scripts;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Transport;

namespace ZB.MOM.WW.ScadaBridge.Transport.Export;

/// <summary>
/// Output of <see cref="DependencyResolver.ResolveAsync"/> — the full closure of
/// entities that need to land in a bundle for the given <see cref="ExportSelection"/>,
/// along with a stable, manifest-ready <c>ContentManifest</c>. Templates are
/// topologically ordered (base before derived) so the importer can apply them
/// in-order without further sorting.
/// </summary>
public sealed record ResolvedExport(
    IReadOnlyList<TemplateFolder> TemplateFolders,
    IReadOnlyList<Template> Templates,
    IReadOnlyList<SharedScript> SharedScripts,
    IReadOnlyList<ExternalSystemDefinition> ExternalSystems,
    IReadOnlyList<ExternalSystemMethod> ExternalSystemMethods,
    IReadOnlyList<DatabaseConnectionDefinition> DatabaseConnections,
    IReadOnlyList<NotificationList> NotificationLists,
    IReadOnlyList<SmtpConfiguration> SmtpConfigs,
    // Inbound API keys are not transported between environments; only methods.
    IReadOnlyList<ApiMethod> ApiMethods,
    IReadOnlyList<ManifestContentEntry> ContentManifest)
{
    // Site/instance-scoped closure. Additive init-only collections with empty
    // defaults so the positional ctor stays source-compatible for callers/tests
    // that only resolve central-config selections (sites/instances stay empty).
    // The resolver opts in via object-initializer. Each <see cref="Instance"/>
    // carries its overrides/bindings on its own navigation collections
    // (AttributeOverrides / AlarmOverrides / NativeAlarmSourceOverrides /
    // ConnectionBindings), populated by the resolver — the serializer reads them
    // off the entity, matching how the central-config entities carry their children.
    //
    // Ordering is fixed by the resolver: Sites by SiteIdentifier; DataConnections
    // by (SiteIdentifier, Name); Instances by UniqueName.

    /// <summary>Sites in the export closure, ordered by <see cref="Site.SiteIdentifier"/>.</summary>
    public IReadOnlyList<Site> Sites { get; init; } = Array.Empty<Site>();

    /// <summary>
    /// Site-scoped <see cref="DataConnection"/>s in the closure, ordered by
    /// (owning site identifier, connection name).
    /// </summary>
    public IReadOnlyList<DataConnection> DataConnections { get; init; } = Array.Empty<DataConnection>();

    /// <summary>
    /// Instances in the closure, ordered by <see cref="Instance.UniqueName"/>. Each
    /// carries its loaded override/binding child collections on its navigation
    /// properties.
    /// </summary>
    public IReadOnlyList<Instance> Instances { get; init; } = Array.Empty<Instance>();

    /// <summary>
    /// SMS provider configurations in the closure, ordered by
    /// <see cref="SmsConfiguration.AccountSid"/>. Mirrors
    /// <see cref="SmtpConfigs"/>; init-only with an empty default so callers that
    /// only resolve other selections keep compiling.
    /// </summary>
    public IReadOnlyList<SmsConfiguration> SmsConfigs { get; init; } = Array.Empty<SmsConfiguration>();
}
