namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.InboundApi;

/// <summary>
/// Request routed from Inbound API to a site to invoke a script on an instance.
/// Used by Route.To("instanceCode").Call("scriptName", params).
/// </summary>
/// <param name="ParentExecutionId">
/// ParentExecutionId: the spawning execution's <c>ExecutionId</c>
/// — for an inbound-API-routed call this is the inbound request's per-request
/// execution id. The site records it as the routed script execution's
/// <c>ParentExecutionId</c> so a spawned execution points back at its spawner.
/// Additive trailing member — null for requests built before the field existed
/// or for routed calls with no spawning execution (e.g. the Central UI sandbox).
/// </param>
public record RouteToCallRequest(
    string CorrelationId,
    string InstanceUniqueName,
    string ScriptName,
    IReadOnlyDictionary<string, object?>? Parameters,
    DateTimeOffset Timestamp,
    Guid? ParentExecutionId = null);

/// <summary>
/// Response from a Route.To() call.
/// </summary>
public record RouteToCallResponse(
    string CorrelationId,
    bool Success,
    object? ReturnValue,
    string? ErrorMessage,
    DateTimeOffset Timestamp);

/// <summary>
/// Request to read attribute(s) from a remote instance.
/// </summary>
/// <param name="ParentExecutionId">
/// ParentExecutionId: mirrors <see cref="RouteToCallRequest.ParentExecutionId"/>.
/// For an inbound-API-routed read this is the inbound request's per-request execution id;
/// future site-side audit emission for routed reads can stamp it as <c>ParentExecutionId</c>
/// so the inbound→site execution-tree link survives the read path. Additive trailing
/// member — null for the Central UI sandbox path or for callers built before the field existed.
/// </param>
public record RouteToGetAttributesRequest(
    string CorrelationId,
    string InstanceUniqueName,
    IReadOnlyList<string> AttributeNames,
    DateTimeOffset Timestamp,
    Guid? ParentExecutionId = null);

/// <summary>
/// Response containing attribute values from a remote instance.
/// </summary>
public record RouteToGetAttributesResponse(
    string CorrelationId,
    IReadOnlyDictionary<string, object?> Values,
    bool Success,
    string? ErrorMessage,
    DateTimeOffset Timestamp);

/// <summary>
/// Request to write attribute(s) on a remote instance.
/// </summary>
/// <param name="ParentExecutionId">
/// ParentExecutionId: mirrors <see cref="RouteToCallRequest.ParentExecutionId"/>.
/// For an inbound-API-routed write this is the inbound request's per-request execution id;
/// site-side audit emission for the underlying device / static-attribute write can stamp
/// it as <c>ParentExecutionId</c> so the inbound→site execution-tree link survives the
/// write path. Additive trailing member — null for the Central UI sandbox path or for
/// callers built before the field existed.
/// </param>
public record RouteToSetAttributesRequest(
    string CorrelationId,
    string InstanceUniqueName,
    IReadOnlyDictionary<string, string> AttributeValues,
    DateTimeOffset Timestamp,
    Guid? ParentExecutionId = null);

/// <summary>
/// Response confirming attribute writes on a remote instance.
/// </summary>
public record RouteToSetAttributesResponse(
    string CorrelationId,
    bool Success,
    string? ErrorMessage,
    DateTimeOffset Timestamp);

/// <summary>
/// Request to block until a remote instance attribute reaches a target value
/// (spec §6 — <c>Route.To("inst").WaitForAttribute(name, targetValue, timeout)</c>).
/// Value-equality across the wire: <see cref="TargetValueEncoded"/> carries the
/// canonical <c>AttributeValueCodec</c>-encoded target; there is no predicate (a
/// cross-process lambda cannot be routed). <see cref="RequireGoodQuality"/> optionally
/// gates the match on Good quality. The site evaluates the match and either matches or
/// times out.
/// </summary>
/// <param name="ParentExecutionId">
/// ParentExecutionId: mirrors <see cref="RouteToCallRequest.ParentExecutionId"/>.
/// For an inbound-API-routed wait this is the inbound request's per-request execution id;
/// future site-side audit emission for routed waits can stamp it as <c>ParentExecutionId</c>
/// so the inbound→site execution-tree link survives the wait path. Additive trailing
/// member — null for the Central UI sandbox path or for callers built before the field existed.
/// </param>
/// <param name="RequireGoodQuality">
/// Quality-gated ("Good"-only) mode (spec §4.2): when true, a value reaching the target at
/// Bad/Uncertain quality is NOT a match — the site holds the wait until the value satisfies
/// the target at Good quality (or times out). Additive trailing member; defaults to
/// <see langword="false"/> (quality-agnostic) so older callers and the wire default are unchanged.
/// </param>
public record RouteToWaitForAttributeRequest(
    string CorrelationId,
    string InstanceUniqueName,
    string AttributeName,
    string? TargetValueEncoded,
    TimeSpan Timeout,
    DateTimeOffset Timestamp,
    Guid? ParentExecutionId = null,
    bool RequireGoodQuality = false);

/// <summary>
/// Response from a remote attribute wait. <see cref="Success"/>/<see cref="ErrorMessage"/>
/// convey the routing-level outcome (e.g. instance-not-found); <see cref="Matched"/>,
/// <see cref="TimedOut"/>, <see cref="Value"/>, and <see cref="Quality"/> convey the wait
/// outcome itself. When <see cref="Success"/> is <c>true</c>, exactly one of
/// <see cref="Matched"/>/<see cref="TimedOut"/> holds: <see cref="Matched"/> means the
/// attribute reached the target value (with <see cref="Value"/>/<see cref="Quality"/>
/// captured at the match), <see cref="TimedOut"/> means the deadline elapsed first.
/// </summary>
public record RouteToWaitForAttributeResponse(
    string CorrelationId,
    bool Matched,
    object? Value,
    string? Quality,
    bool TimedOut,
    bool Success,
    string? ErrorMessage,
    DateTimeOffset Timestamp);
