using System; using System.Collections.Generic; using System.Linq; namespace SessionZero.Data; [SzfObject(SzfObjectType.Dataset, "dataset")] public class Dataset : SzfObject { public string DatasetType { get; set; } = string.Empty; public string ImageUrl { get; set; } = string.Empty; // New field for dataset image public List Entries { get; set; } = new(); public Dictionary Metadata { get; set; } = new(); // To store other metadata fields public override SzfObjectType ObjectType => SzfObjectType.Dataset; public override void PopulateFromMetadata(Dictionary metadata) { base.PopulateFromMetadata(metadata); if (metadata.TryGetValue("Type", out var typeField)) DatasetType = typeField.Value?.ToString() ?? string.Empty; if (metadata.TryGetValue("ImageUrl", out var imageUrlField)) ImageUrl = imageUrlField.Value?.ToString() ?? string.Empty; // Store any other metadata fields not explicitly mapped foreach (var kvp in metadata) { if (!new[] { "Name", "Version", "GUID", "Description", "Author", "Type", "ImageUrl" } .Contains(kvp.Key, StringComparer.OrdinalIgnoreCase)) { Metadata[kvp.Key] = kvp.Value.Value!; } } } public override void ParseSections(List sections) { var currentEntry = (DatasetEntry?)null; foreach (var szfSection in sections) { if (szfSection.Name.StartsWith("Entry:", StringComparison.OrdinalIgnoreCase)) { currentEntry = new DatasetEntry { Name = szfSection.Name.Replace("Entry:", "").Trim() }; foreach (var field in szfSection.Fields) { currentEntry.Fields.Add(ConvertToDatasetField(field)); } Entries.Add(currentEntry); } else if (szfSection.Name.StartsWith("Entry.", StringComparison.OrdinalIgnoreCase) && currentEntry != null) { // Handle subsections by finding their parent entry var parts = szfSection.Name.Split('.'); if (parts.Length >= 2 && parts[0].Equals("Entry", StringComparison.OrdinalIgnoreCase) && parts[1].Equals(currentEntry.Name, StringComparison.OrdinalIgnoreCase)) { var subSection = new DatasetSection { Name = string.Join(".", parts.Skip(2)).Trim() // Name for the subsection }; foreach (var field in szfSection.Fields) { subSection.Fields.Add(ConvertToDatasetField(field)); } currentEntry.Sections.Add(subSection); } } } } private DatasetField ConvertToDatasetField(SzfField szfField) { // You would typically parse more properties here like Description, IsRequired etc. // For simplicity, only Name, Type and Value are mapped for now. return new DatasetField { Name = szfField.Name, Type = ParseDatasetFieldType(szfField.Type), Value = szfField.Value }; } private DatasetFieldType ParseDatasetFieldType(string typeString) { return typeString.ToLower() switch { "text" => DatasetFieldType.Text, "text-field" => DatasetFieldType.TextField, "number" => DatasetFieldType.Number, "bool" => DatasetFieldType.Boolean, "calculated" => DatasetFieldType.Calculated, "system" => DatasetFieldType.System, "dataset-reference" => DatasetFieldType.DatasetReference, "dataset-type" => DatasetFieldType.DatasetType, "dataset-reference-multiple" => DatasetFieldType.DatasetReferenceMultiple, "dataset-type-multiple" => DatasetFieldType.DatasetTypeMultiple, "group" => DatasetFieldType.Group, _ => DatasetFieldType.Text // Default to text if unknown }; } public override void GenerateMetadata(SzfFieldWriter writer) { // Call base to ensure common metadata is generated first if base had any specific generation logic base.GenerateMetadata(writer); writer.WriteField("Type", "text", DatasetType); if (!string.IsNullOrEmpty(ImageUrl)) writer.WriteField("ImageUrl", "text", ImageUrl); // Write any other dynamic metadata foreach (var kvp in Metadata) { writer.WriteField(kvp.Key, "text", kvp.Value); // Assuming text for generic metadata for now } } public override void GenerateContent(SzfFieldWriter writer) { foreach (var entry in Entries) { writer.AppendSectionHeader($"Entry: {entry.Name}"); foreach (var field in entry.Fields) { writer.WriteField(field.Name, field.Type, field.Value); } foreach (var section in entry.Sections) { GenerateDatasetSection(writer, section, $"Entry.{entry.Name}"); } writer.AppendLine(); } } private void GenerateDatasetSection(SzfFieldWriter writer, DatasetSection section, string parentPath) { var sectionPath = $"{parentPath}.{section.Name}"; writer.AppendSectionHeader(sectionPath); foreach (var field in section.Fields) { writer.WriteField(field.Name, field.Type, field.Value); } foreach (var subsection in section.Subsections) { GenerateDatasetSection(writer, subsection, sectionPath); } } public override SzfValidationResult Validate() { var result = base.Validate(); if (string.IsNullOrWhiteSpace(DatasetType)) result.AddError("DatasetType is required for Dataset"); if (!Entries.Any()) result.AddWarning("Dataset contains no entries."); return result; } } public class DatasetEntry { public string Name { get; set; } = string.Empty; public List Fields { get; set; } = new(); public List Sections { get; set; } = new(); // For nested sections within an entry } public class DatasetSection { public string Name { get; set; } = string.Empty; public List Fields { get; set; } = new(); public List Subsections { get; set; } = new(); } public class DatasetField { public string Name { get; set; } = string.Empty; public DatasetFieldType Type { get; set; } public object? Value { get; set; } public string? Description { get; set; } public bool IsRequired { get; set; } public object? DefaultValue { get; set; } public string? Formula { get; set; } public string? ReferencedDatasetId { get; set; } // For dataset-reference types, stores the ID public string? ReferencedDatasetType { get; set; } // For dataset-type types, stores the type public bool AllowMultiple { get; set; } public List GroupFields { get; set; } = new(); // For group fields } public enum DatasetFieldType { Text, TextField, Number, Boolean, Calculated, System, DatasetReference, DatasetType, DatasetReferenceMultiple, DatasetTypeMultiple, Group } public class DatasetReference { public string Name { get; set; } = string.Empty; public Guid Guid { get; set; } public string Version { get; set; } = "1.0.0"; public override string ToString() { return $"{Name}|{Guid}|{Version}"; } public static DatasetReference? Parse(string reference) { if (string.IsNullOrWhiteSpace(reference)) return null; var parts = reference.Split('|'); if (parts.Length != 3) return null; // Invalid format if (Guid.TryParse(parts[1], out var guid)) { return new DatasetReference { Name = parts[0], Guid = guid, Version = parts[2] }; } return null; // Invalid GUID format } } public class DatasetValidationResult : SzfValidationResult { // Specific validation results for datasets can go here if needed }