using Strata.SqlTools.SqlBreakdown.Interfaces.Core;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Strata.SqlTools.SqlBreakdown.Expressions;
///
/// Represents a reference to a property from an input data source, typically used for
/// dynamic data binding in query construction. Used when building queries that reference
/// external data sources by GUID identifiers.
///
///
/// This expression type is used in scenarios where data comes from registered data
/// sources (like data tables or dimensions) that are identified by GUIDs. The
/// expression can reference a primary data source and optionally a secondary data source
/// for hierarchical or relational lookups.
///
///
///
/// // Reference a simple property from a data source
/// var patientName = new InputPropertyExpression(
/// dataSourceGuid: Guid.Parse("41639c8f-fecf-4449-b6e6-53f796c0c3e4"),
/// dataKeyLookup: "PatientName"
/// );
///
/// // Reference a property with a secondary data source (dimension lookup)
/// var patientType = new InputPropertyExpression(
/// dataSourceGuid: Guid.Parse("41639c8f-fecf-4449-b6e6-53f796c0c3e4"),
/// secondaryDataSource: Guid.Parse("6ef6b1f7-a50c-4198-8866-140bb82e2dda"),
/// dataKeyLookup: "PatientTypeRollupName"
/// );
///
///
public class InputPropertyExpression : Expression
{
///
/// Gets the GUID identifier of the primary data source.
///
///
/// The data source GUID, typically representing a data table or primary data entity.
///
///
/// 41639c8f-fecf-4449-b6e6-53f796c0c3e4 - the data table id of PES
///
public Guid DataSourceGuid { get; }
///
/// Gets the optional GUID identifier of a secondary data source.
///
///
/// The secondary data source GUID, typically representing a dimension or lookup table.
/// Null if no secondary source is required.
///
///
/// 6ef6b1f7-a50c-4198-8866-140bb82e2dda - the dimension id of the Patient Type
/// Rollup dimension
///
public Guid? SecondaryDataSource { get; }
///
/// Gets the key name used to look up the data value.
///
///
/// The property or column name within the data source.
///
/// "PatientTypeRollupName"
public string DataKeyLookup { get; }
///
/// Initializes a new instance of the class
/// with a primary data source.
///
/// The GUID of the primary data source.
/// The key name for data lookup.
///
/// Example:
///
/// var property = new InputPropertyExpression(
/// Guid.Parse("41639c8f-fecf-4449-b6e6-53f796c0c3e4"),
/// "PatientName");
///
///
public InputPropertyExpression(Guid dataSourceGuid, string dataKeyLookup) : this(dataSourceGuid, null, dataKeyLookup)
{
}
///
/// Initializes a new instance of the class
/// with primary and optional secondary data sources.
///
/// The GUID of the primary data source.
///
/// The optional GUID of the secondary data source.
///
/// The key name for data lookup.
///
/// Example with secondary data source:
///
/// var property = new InputPropertyExpression(
/// Guid.Parse("41639c8f-fecf-4449-b6e6-53f796c0c3e4"),
/// Guid.Parse("6ef6b1f7-a50c-4198-8866-140bb82e2dda"),
/// "PatientTypeRollupName");
///
///
public InputPropertyExpression(Guid dataSourceGuid, Guid? secondaryDataSource, string dataKeyLookup)
{
DataSourceGuid = dataSourceGuid;
SecondaryDataSource = secondaryDataSource;
DataKeyLookup = dataKeyLookup;
}
public override T Accept(IVisitor visitor)
{
return visitor.VisitInputPropertyExpression(this);
}
}
public class CollectionInputPropertyExpression : InputPropertyExpression
{
public CollectionInputPropertyExpression(Guid dataSourceGuid, Guid secondaryDataSource, string dataKeyLookup)
: base(dataSourceGuid, secondaryDataSource, dataKeyLookup)
{
}
public InputPropertyExpression? ItemProperty { get; }
public override T Accept(IVisitor visitor)
{
throw new NotImplementedException();
}
}
public interface IFlatData : IDictionary
{
string RowIdKey { get; }
long RowId { get; }
}
public class MyFlatData : Dictionary, IFlatData
{
private readonly Lazy _rowId;
public MyFlatData() : this(new Dictionary())
{
}
public MyFlatData(IDictionary rawData) : this(rawData, "RowID")
{
}
public MyFlatData(IDictionary rawData, string rowIdKey) : base(rawData)
{
RowIdKey = rowIdKey;
_rowId = new Lazy(() => this.GetValue(RowIdKey), false);
}
public string RowIdKey { get; }
public long RowId => _rowId.Value;
}
public class FlatData : IFlatData
{
private readonly IDictionary _data;
private readonly Lazy _rowId;
public FlatData() : this(new Dictionary(), "RowID")
{
}
public FlatData(IDictionary rawData, string rowIdKey)
{
_data = rawData;
RowIdKey = rowIdKey;
_rowId = new Lazy(() => this.GetValue(RowIdKey), false);
}
public string RowIdKey { get; }
public long RowId => _rowId.Value;
public IEnumerator> GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_data).GetEnumerator();
}
public void Add(KeyValuePair item)
{
_data.Add(item);
}
public void Clear()
{
_data.Clear();
}
public bool Contains(KeyValuePair item)
{
return _data.Contains(item);
}
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
_data.CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair item)
{
return _data.Remove(item);
}
public int Count => _data.Count;
public bool IsReadOnly { get; }
public void Add(string key, object value)
{
_data.Add(key, value);
}
public bool ContainsKey(string key)
{
return _data.ContainsKey(key);
}
public bool Remove(string key)
{
throw new NotImplementedException();
}
public bool TryGetValue(string key, out object value)
{
return _data.TryGetValue(key, out value!);
}
public IEnumerable Keys => _data.Keys;
ICollection