// SzfObject.cs using System; using System.Collections.Generic; using System.Reflection; namespace SessionZero.Data; /// /// Represents common metadata for all SzfObjects. /// public class SzfMetadata { public string Name { get; set; } = string.Empty; public Version? Version { get; set; } public Guid Guid { get; set; } public string? Description { get; set; } public string? Author { get; set; } } public abstract class SzfObject { /// /// The unique string identifier for this SzfObject type, derived from its SzfObjectAttribute. /// public string TypeIdentifier { get; } /// /// Common metadata for all SzfObjects. /// public SzfMetadata Metadata { get; set; } = new SzfMetadata(); /// /// Default constructor that reads the TypeIdentifier from the SzfObjectAttribute. /// protected SzfObject() { // Read the SzfObjectAttribute from the concrete class type var attribute = GetType().GetCustomAttribute(); if (attribute == null) { // This indicates a missing attribute, which means the class is not properly defined as an SzfObject. throw new InvalidOperationException( $"SzfObject class '{GetType().Name}' is missing the SzfObjectAttribute. All concrete SzfObject types must have this attribute."); } TypeIdentifier = attribute.TypeIdentifier; // Initialize metadata with a new GUID, this is a default, can be overridden by parsing Metadata.Guid = Guid.NewGuid(); } /// /// Populates the object's metadata from a dictionary of parsed SzfFields. /// This method is intended to be overridden by derived classes to handle their specific metadata. /// /// A dictionary of metadata fields. public virtual void PopulateFromMetadata(Dictionary metadata) { if (metadata.TryGetValue("Name", out var nameField)) Metadata.Name = nameField.Value?.ToString() ?? string.Empty; if (metadata.TryGetValue("Version", out var versionField)) { if (Version.TryParse(versionField.Value?.ToString(), out var ver)) { Metadata.Version = ver; } } if (metadata.TryGetValue("GUID", out var guidField)) { if (Guid.TryParse(guidField.Value?.ToString() ?? string.Empty, out var guid)) { Metadata.Guid = guid; } } if (metadata.TryGetValue("Description", out var descriptionField)) Metadata.Description = descriptionField.Value?.ToString(); if (metadata.TryGetValue("Author", out var authorField)) Metadata.Author = authorField.Value?.ToString(); } /// /// Parses the sections of the Szf object from a flat list of SzfSection objects /// and constructs the object's internal data structure. This is an abstract method /// that must be implemented by derived classes. /// /// A list of parsed SzfSections. public abstract void ParseSections(List sections); /// /// Generates the metadata section of the Szf file using the provided writer. /// This method is virtual and can be extended by derived classes to add their specific metadata. /// /// The SzfFieldWriter to use for writing. public virtual void GenerateMetadata(SzfFieldWriter writer) { // Write standard metadata fields common to all SzfObjects writer.AppendSectionHeader("Metadata"); // Corrected method call writer.WriteField("Name", "text", Metadata.Name); writer.WriteField("Version", "text", Metadata.Version?.ToString() ?? string.Empty); // Ensure Version is not null writer.WriteField("GUID", "text", Metadata.Guid.ToString()); if (!string.IsNullOrEmpty(Metadata.Description)) writer.WriteField("Description", "text-field", Metadata.Description); if (!string.IsNullOrEmpty(Metadata.Author)) writer.WriteField("Author", "text", Metadata.Author); writer.AppendLine(); // Corrected method call to end section with a newline } /// /// Generates the content sections of the Szf file using the provided writer. /// This is an abstract method that must be implemented by derived classes. /// /// The SzfFieldWriter to use for writing. public abstract void GenerateContent(SzfFieldWriter writer); /// /// Validates the current state of the Szf object. /// This method is virtual and can be extended by derived classes to add their specific validation rules. /// /// A SzfValidationResult indicating any errors or warnings. public virtual SzfValidationResult Validate() { var result = new SzfValidationResult(); if (string.IsNullOrWhiteSpace(Metadata.Name)) result.AddError("Name is required for SzfObject"); if (Metadata.Version == null) result.AddError("Version is required for SzfObject"); if (Metadata.Guid == Guid.Empty) result.AddError("GUID is required for SzfObject"); return result; } } public class SzfValidationResult { public bool IsValid { get; set; } = true; public List Errors { get; set; } = []; public List Warnings { get; set; } = []; public void AddError(string error) { Errors.Add(error); IsValid = false; } public void AddWarning(string warning) { Warnings.Add(warning); } } public class SzfField { public string Name { get; set; } = string.Empty; public string Type { get; set; } = string.Empty; public object? Value { get; set; } }