using ZB.MOM.WW.OtOpcUa.Core.Abstractions;

namespace ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts;

/// <summary>
///     One SQL-backed OPC UA variable — the typed form of an authored raw tag's <c>TagConfig</c> blob
///     (design §5.2 / §5.3), produced by <see cref="SqlEquipmentTagParser.TryParse"/>.
///     <para><b>Every string here is captured verbatim from the authored blob and is NEVER concatenated
///     into SQL.</b> Value-bearing fields (<see cref="KeyValue"/>, <see cref="RowSelectorValue"/>) are bound
///     as <c>DbParameter</c>s by the reader; identifier-bearing fields (<see cref="Table"/>,
///     <see cref="KeyColumn"/>, <see cref="ValueColumn"/>, <see cref="TimestampColumn"/>,
///     <see cref="ColumnName"/>, <see cref="RowSelectorColumn"/>,
///     <see cref="RowSelectorTopByTimestamp"/>) must be validated against <c>INFORMATION_SCHEMA</c> and
///     dialect-quoted by the reader before they reach a command text. Sanitising here would corrupt
///     legitimate values, so the parser deliberately does not.</para>
/// </summary>
/// <param name="Name">
///     The tag's identity — its <b>RawPath</b>, exactly as handed to the parser. The driver's forward
///     router keys published values on this, so it must never be derived from the blob's contents.
/// </param>
/// <param name="Model">Which tag→value mapping this tag uses. v1 accepts KeyValue and WideRow only.</param>
/// <param name="Table">The table or view to read (e.g. <c>dbo.TagValues</c>).</param>
/// <param name="KeyColumn"><see cref="SqlTagModel.KeyValue"/>: the column matched against <see cref="KeyValue"/>.</param>
/// <param name="KeyValue"><see cref="SqlTagModel.KeyValue"/>: this tag's key — <b>bound</b>, never interpolated.</param>
/// <param name="ValueColumn"><see cref="SqlTagModel.KeyValue"/>: the column the value is read from.</param>
/// <param name="TimestampColumn">Optional source-timestamp column; absent ⇒ the driver stamps the poll time.</param>
/// <param name="ColumnName"><see cref="SqlTagModel.WideRow"/>: the column this tag reads from the selected row.</param>
/// <param name="RowSelectorColumn"><see cref="SqlTagModel.WideRow"/>: the <c>whereColumn</c> that picks the row.</param>
/// <param name="RowSelectorValue"><see cref="SqlTagModel.WideRow"/>: the <c>whereValue</c> — <b>bound</b>, never interpolated.</param>
/// <param name="RowSelectorTopByTimestamp"><see cref="SqlTagModel.WideRow"/>: newest-row selector — the timestamp column to order by, when no where-pair is authored.</param>
/// <param name="DeclaredType">
///     Optional explicit type override from the blob's <c>type</c> field. <see langword="null"/> ⇒ the
///     driver infers the type from the result set's column metadata.
/// </param>
public sealed record SqlTagDefinition(
    string Name,
    SqlTagModel Model,
    string Table,
    string? KeyColumn = null,
    string? KeyValue = null,
    string? ValueColumn = null,
    string? TimestampColumn = null,
    string? ColumnName = null,
    string? RowSelectorColumn = null,
    string? RowSelectorValue = null,
    string? RowSelectorTopByTimestamp = null,
    DriverDataType? DeclaredType = null);
