using System.Globalization; using Inspectron.Epson.PrintServer.Printers.Utils; using Inspectron.Epson.Templates.Configuration; using Inspectron.Epson.Templates.Interpreter; using Inspectron.Epson.Templates.Language; using Inspectron.Epson.Templates.Language.Nodes; using Inspectron.Epson.Templates.Storage; using Inspectron.Epson.Templates.Validation; namespace Inspectron.Epson.Templates; public class TemplateEngine { private readonly ITemplateStorage _storage; private readonly PrinterProfileRegistry _profileRegistry; private readonly TemplateResolver _resolver; private readonly CultureInfo? _culture; public TemplateEngine( ITemplateStorage storage, PrinterProfileRegistry profileRegistry, TemplateResolver resolver, CultureInfo? culture = null) { _storage = storage ?? throw new ArgumentNullException(nameof(storage)); _profileRegistry = profileRegistry ?? throw new ArgumentNullException(nameof(profileRegistry)); _resolver = resolver ?? throw new ArgumentNullException(nameof(resolver)); _culture = culture; } public List Render(int receiptType, byte printerId, string jsonData) { var profile = _profileRegistry.GetProfile(printerId); var templatePath = _resolver.Resolve(receiptType, profile.Id); return RenderTemplate(templatePath, profile, jsonData); } public List Render(int receiptType, string profileId, string jsonData) { var profile = _profileRegistry.GetProfile(profileId); var templatePath = _resolver.Resolve(receiptType, profileId); return RenderTemplate(templatePath, profile, jsonData); } public List RenderTemplate(string templatePath, PrinterProfile profile, string jsonData) { var templateSource = _storage.Load(templatePath); if (templateSource == null) { throw new FileNotFoundException($"Template not found: {templatePath}"); } return RenderSource(templateSource, profile, jsonData); } public List RenderSource(string templateSource, PrinterProfile profile, string jsonData) { var template = Parse(templateSource); var interpreter = new TemplateInterpreter(profile, _culture); return interpreter.Interpret(template, jsonData); } public TemplateValidationResult Validate(string templateSource, PrinterProfile? profile = null) { var validator = new TemplateValidator(profile); return validator.Validate(templateSource); } public TemplateValidationResult ValidateTemplate(string templatePath, PrinterProfile? profile = null) { var templateSource = _storage.Load(templatePath); if (templateSource == null) { return TemplateValidationResult.WithErrors( new TemplateError( TemplateErrorCode.RTL001_UnexpectedToken, $"Template not found: {templatePath}", new SourcePosition(0, 0))); } return Validate(templateSource, profile); } public void ReloadTemplates() { _storage.Reload(); } private TemplateNode Parse(string templateSource) { var lexer = new Lexer(templateSource); var lexerResult = lexer.Tokenize(); if (lexerResult.HasErrors) { var firstError = lexerResult.Errors.First(); throw new InterpreterException( $"Lexer error: {firstError.Message}", firstError.Position); } var parser = new Parser(lexerResult.Tokens); var parseResult = parser.Parse(); if (parseResult.HasErrors) { var firstError = parseResult.Errors.First(); throw new InterpreterException( $"Parse error: {firstError.Message}", firstError.Position); } return parseResult.Template; } }