using System.Text.RegularExpressions; using static AiAgent.Core.Constant.ProgramConstants; namespace AiAgent.Core.Helpers; public static class GenericHelper { private static object _threadLock = new(); public static string LogFile => Path.Combine(Output, "application.log"); public static void InitialiseLog() => File.WriteAllText(LogFile, string.Empty); public static void Log(string message) { Console.WriteLine(message); lock (_threadLock) File.AppendAllText(LogFile, message + Environment.NewLine); } public static void LogNoLine(string message) { Console.Write(message); lock (_threadLock) File.AppendAllText(LogFile, message); } /// /// Removes reference tags like [Ref: 1, 2, 3] from a string. /// /// The text to clean. /// The text with reference tags removed. public static string CleanReferences(string text) { if (string.IsNullOrEmpty(text)) return text; // This regex finds and removes patterns like "[Ref: 1, 2, 3]" including any preceding space. string pattern = @"\s*\[Ref:[^\]]+\]"; return Regex.Replace(text, pattern, ""); } private static int _outputFileCounter = 0; /// /// Saves the specified content to a new output file with a unique name in the specified directory. /// /// The method ensures that each output file has a unique name by appending a counter to the file /// name. If does not include a directory, the default output directory is /// used. /// The desired output file name, including the directory path. If the directory is not specified, the default /// output directory is used. /// The content to be written to the output file. /// A task that represents the asynchronous operation. /// Thrown if is null or empty. public static async Task SaveOutput(string outputFileName, string content) { //_outputFileCounter++; //string filename = Path.GetFileName(outputFileName) ?? throw new ArgumentException("Output file name cannot be null or empty.", nameof(outputFileName)); //string orderedFileFolder = Path.Combine(Output, "Ordered Files"); //string newFileName = Path.Combine(orderedFileFolder, $"Output {_outputFileCounter} - {filename}"); //Directory.CreateDirectory(orderedFileFolder); await File.WriteAllTextAsync(outputFileName, content); //await File.WriteAllTextAsync(newFileName, content); } public static string GetStringBetween(string text, string del1, string del2) { // 1. Find the starting position of the first delimiter. int pos1 = text.IndexOf(del1); if (pos1 == -1) { return string.Empty; // Or null, depending on your preference } // 2. Calculate the starting position of the desired substring. // This is the position of the first delimiter plus its length. int startIndex = pos1 + del1.Length; // 3. Find the starting position of the second delimiter, // searching only *after* the first delimiter. int pos2 = text.IndexOf(del2, startIndex); if (pos2 == -1) { return string.Empty; // Or null } // 4. Calculate the length of the desired substring. int length = pos2 - startIndex; // 5. Extract and return the substring. return text.Substring(startIndex, length); } // /// // /// Parses an article file with sections denoted by {SectionName} and returns a dictionary. // /// // /// The path to the article file. // /// A dictionary where the key is the section name and the value is the section content. // public static Dictionary ParseArticle(string filePath) // { // var sections = new Dictionary(); // if (!File.Exists(filePath)) // { // Console.WriteLine($"Error: File not found at {filePath}"); // return sections; // } // string content = File.ReadAllText(filePath); // // This regex finds a section title in curly braces, captures it, // // and then captures the content until the next section title or the end of the file. // // RegexOptions.Singleline ensures that '.' matches newline characters. // string pattern = @"{(?[^}]+)}\s*(?.*?)(?=\s*{[^}]+}\s*|$)"; // MatchCollection matches = Regex.Matches(content, pattern, RegexOptions.Singleline); // foreach (Match match in matches) // { // // Extract the captured group values by name. // string sectionName = match.Groups["name"].Value.Trim(); // string sectionContent = match.Groups["content"].Value.Trim(); // // Add to the dictionary. If a section name is duplicated, the last one wins. // sections[sectionName] = sectionContent; // } // return sections; // } }