using System.Text.RegularExpressions; using LAPS_XMLQC_Service.Models; //using SystemRegexMatch = System.Text.RegularExpressions.Match; using MyMatch = LAPS_XMLQC_Service.Models.Matches; using System.Collections.Generic; using System.Threading.Tasks; //using System.Threading; using System.IO; using System.Linq; using System; using System.Collections.Concurrent; //using Microsoft.AspNetCore.Mvc; namespace LAPS_XMLQC_Service.Services { public class FileSearchService : FileSearchServiceBase { private readonly RegexPatternService _regexPatternService; public enum Status { Load, Preview, Accept, Replaced, Failed, Deleted } public FileSearchService(RegexPatternService regexPatternService) { _regexPatternService = regexPatternService; } public async Task> SearchFiles(string directoryPath, string? searchTerm, string fileType, bool caseInsensitive, bool singleLine, bool multiLine, bool ignoreWhitespace, bool explicitCapture) { var regexOptions = RegexOptions.None; var results = new ConcurrentBag(); if (caseInsensitive) regexOptions |= RegexOptions.IgnoreCase; if (singleLine) regexOptions |= RegexOptions.Singleline; if (multiLine) regexOptions |= RegexOptions.Multiline; if (ignoreWhitespace) regexOptions |= RegexOptions.IgnorePatternWhitespace; if (explicitCapture) regexOptions |= RegexOptions.ExplicitCapture; regexOptions |= RegexOptions.Compiled; var patterns = _regexPatternService.GetRegexPatterns(); var files = Directory.GetFiles(directoryPath, fileType, SearchOption.AllDirectories); var tasks = patterns.Select(pattern => Task.Run(async () => { var searchTerm = pattern.Pattern; var regex = new Regex(searchTerm, regexOptions); var fileTasks = files.Select(async file => { var content = await File.ReadAllTextAsync(file); content = content.Replace("", ""); var matches = regex.Matches(content); if (matches.Count > 0) { results.Add(new MatchedResult { FileName = Path.GetFileName(file), FilePath = file, DirectoryPath = directoryPath, Content = content, PreviewContent = "", ResultCount = matches.Count, FinalContent = "", Status = Status.Load.ToString(), PatternResults = new List { new PatternResult { Pattern = searchTerm, Matches = matches .Select(m => new MyMatch { Index = m.Index, Content = m.Value, LineNumber = CalculateLineNumber(content, m.Index) }).ToList() } } }); } }); await Task.WhenAll(fileTasks); })); await Task.WhenAll(tasks); return results.ToList(); //var regexOptions = RegexOptions.None; //var results = new List(); //if (caseInsensitive) regexOptions |= RegexOptions.IgnoreCase; //if (singleLine) regexOptions |= RegexOptions.Singleline; //if (multiLine) regexOptions |= RegexOptions.Multiline; //if (ignoreWhitespace) regexOptions |= RegexOptions.IgnorePatternWhitespace; //if (explicitCapture) regexOptions |= RegexOptions.ExplicitCapture; //regexOptions |= RegexOptions.Compiled; //var patterns = _regexPatternService.GetRegexPatterns(); //var files = Directory.GetFiles(directoryPath, fileType, SearchOption.AllDirectories); //foreach (var pattern in patterns) //{ // searchTerm = pattern.Pattern; // var regex = new Regex(searchTerm, regexOptions); // foreach (var file in files) // { // var content = await File.ReadAllTextAsync(file); // var matches = regex.Matches(content); // if (matches.Count > 0) // { // results.Add(new MatchedResult // { // FileName = Path.GetFileName(file), // FilePath = file, // DirectoryPath = directoryPath, // Content = content, // PreviewContent = "", // ResultCount = matches.Count, // FinalContent = "", // Status = Status.Load.ToString(), // PatternResults = new List // { // new PatternResult // { // Pattern = searchTerm, // Matches = matches // .Select(m => new MyMatch // { // Index = m.Index, // Content = m.Value, // LineNumber = CalculateLineNumber(content, m.Index) // }).ToList() // } // } // }); // } // } //} //return results; //// Validate and format the file type //if (fileType.StartsWith('.')) //{ // fileType = "*" + fileType; //} //else if (!fileType.StartsWith('*') && !fileType.StartsWith('.')) //{ // fileType = "*." + fileType; //} //var results = new List(); //Regex? regex = null; //if (!string.IsNullOrEmpty(searchTerm)) //{ // var regexOptions = RegexOptions.None; // // Set regex options based on parameters // if (caseInsensitive) // regexOptions |= RegexOptions.IgnoreCase; // if (singleLine) // regexOptions |= RegexOptions.Singleline; // if (multiLine) // regexOptions |= RegexOptions.Multiline; // if (ignoreWhitespace) // regexOptions |= RegexOptions.IgnorePatternWhitespace; // if (explicitCapture) // regexOptions |= RegexOptions.ExplicitCapture; // regexOptions |= RegexOptions.Compiled; // regex = new Regex(searchTerm, regexOptions); //} //// Limit the degree of parallelism for better resource management //int maxDegreeOfParallelism = 5; //var semaphore = new SemaphoreSlim(maxDegreeOfParallelism); //var fileTasks = Directory.GetFiles(directoryPath, fileType, SearchOption.AllDirectories) // .Select(async file => // { // await semaphore.WaitAsync(); // try // { // var matches = new List(); // var content = await File.ReadAllTextAsync(file); // var matchedResult = new MatchedResult // { // FileName = Path.GetFileName(file), // Content = content, // PatternResults = new List() // }; // // Perform regex matching on the file content // if (regex != null) // { // foreach (SystemRegexMatch match in regex!.Matches(content)) // { // matches.Add(new MyMatch // { // Index = match.Index, // Content = match.Value, // LineNumber = CalculateLineNumber(content, match.Index) // }); // } // } // // Add the pattern result // var patternResult = new PatternResult { Pattern = searchTerm, Matches = matches }; // matchedResult.ResultCount = matches.Count; // matchedResult.PatternResults!.Add(patternResult); // return matchedResult; // } // catch (Exception ex) // { // // Handle the exception, possibly logging it // Console.WriteLine($"Error processing file {file}: {ex.Message}"); // return null; // } // finally // { // semaphore.Release(); // Release the semaphore // } // }); //// Execute all file processing tasks in parallel //var taskResults = await Task.WhenAll(fileTasks); //results = taskResults.Where(result => result != null).Cast().ToList(); //return results; } public async Task> PreviewOrReplaceAll(string directoryPath, string? searchTerm, string replacementText, string fileType, bool caseInsensitive, bool singleLine, bool multiLine, bool ignoreWhitespace, bool explicitCapture, string options) { // Configure regex options if (string.IsNullOrEmpty(searchTerm)) throw new ArgumentException("Search term cannot be empty."); // Configure regex options if (string.IsNullOrEmpty(replacementText)) throw new ArgumentException("Replacement text cannot be empty."); var regexOptions = RegexOptions.None; if (caseInsensitive) regexOptions |= RegexOptions.IgnoreCase; if (singleLine) regexOptions |= RegexOptions.Singleline; if (multiLine) regexOptions |= RegexOptions.Multiline; if (ignoreWhitespace) regexOptions |= RegexOptions.IgnorePatternWhitespace; if (explicitCapture) regexOptions |= RegexOptions.ExplicitCapture; // regexOptions |= RegexOptions.Compiled; var results = new List(); try { var regex = new Regex(searchTerm, regexOptions); var files = Directory.GetFiles(directoryPath, fileType, SearchOption.AllDirectories); foreach (var file in files) { var content = await File.ReadAllTextAsync(file); // content = content.Replace("", ""); var matches = regex.Matches(content); // Generate preview var previewContent = regex.Replace(content, replacementText); MatchCollection match= regex.Matches(previewContent); if (matches.Count > 0) { results.Add(new MatchedResult { FileName = Path.GetFileName(file), FilePath = file, DirectoryPath = directoryPath, Content = content, PreviewContent = previewContent, ResultCount = matches.Count, FinalContent = "", Status = Status.Preview.ToString(), PatternResults = new List { new PatternResult { Pattern = searchTerm, Matches = matches .Select(m => new MyMatch { Index = m.Index, Content = m.Value, LineNumber = CalculateLineNumber(content, m.Index) }).ToList() } } }); } } if(options.Equals("ReplaceAll")) { results = await ApplyChanges(results); } } catch (Exception ex) { } return results; } public async Task ApplyChange(MatchedResult result) { string filePath = string.Empty; if (!string.IsNullOrEmpty(result.PreviewContent)) { //string outputDirectory = Path.Combine(Path.GetDirectoryName(result.FilePath), "OUT"); //if (!Directory.Exists(outputDirectory)) //{ // Directory.CreateDirectory(outputDirectory); // Creates the folder if it doesn't exist //} // Set the file path within the "out" folder //filePath = Path.Combine(outputDirectory, Path.GetFileName(result.FilePath)); string outputDirectory = result.DirectoryPath.Replace(@"\IN", @"\OUT"); filePath = Path.Combine(outputDirectory, Path.GetFileName(result.FilePath)); // Write the preview content to the file await File.WriteAllTextAsync(filePath, result.PreviewContent); result.OutputFilePath = filePath; result.Status = Status.Accept.ToString(); } // Return the result return result; // string filePath = string.Empty; // if (!string.IsNullOrEmpty(result.PreviewContent)) // { // filePath = result.FilePath; // await File.WriteAllTextAsync(filePath, result.PreviewContent); // Write the preview content to the file // // Update the final content // // result.FinalContent = result.PreviewContent; // // result.Content = result.PreviewContent; // // result.PreviewContent = ""; // result.Status = "Replaced"; //} //return result; } public async Task> ApplyChanges(List results) { string filePath = string.Empty; string outputDirectory = string.Empty; foreach (var result in results) { if (!string.IsNullOrEmpty(result.PreviewContent)) { //string outputDirectory = Path.Combine(Path.GetDirectoryName(result.FilePath), "OUT"); //if (!Directory.Exists(outputDirectory)) //{ // Directory.CreateDirectory(outputDirectory); // Creates the folder if it doesn't exist //} //// Set the file path within the "out" folder //filePath = Path.Combine(outputDirectory, Path.GetFileName(result.FilePath)); if (string.IsNullOrEmpty(outputDirectory)) { outputDirectory = result.DirectoryPath.Replace(@"\IN", @"\OUT"); } filePath = Path.Combine(outputDirectory, Path.GetFileName(result.FilePath)); // Write the preview content to the file await File.WriteAllTextAsync(filePath, result.PreviewContent); result.OutputFilePath = filePath; result.Status = Status.Accept.ToString(); } } return results; //string filePath = string.Empty; //foreach (var result in results) //{ // if (!string.IsNullOrEmpty(result.PreviewContent)) // { // filePath = string.Empty; // filePath = result.FilePath; // await File.WriteAllTextAsync(filePath, result.PreviewContent); // Write the preview content to the file // // Update the final content // //result.FinalContent = result.PreviewContent; // // result.Content = result.PreviewContent; // // result.PreviewContent = ""; // result.Status = "Replaced"; // } //} //return results; } public List Accept(List results) { foreach (var result in results) { try { // Move file and overwrite if it exists File.Move(result.OutputFilePath, result.FilePath, true); result.FinalContent = result.PreviewContent; result.Content = result.PreviewContent; result.Status = Status.Replaced.ToString(); } catch (Exception ex) { // Log the error and update the status to indicate failure Console.WriteLine($"Error processing file {result.OutputFilePath}: {ex.Message}"); result.Status = Status.Failed.ToString(); } } return results; } public List Reject(List results) { foreach (var result in results) { try { File.Delete(result.OutputFilePath); result.Status = Status.Deleted.ToString(); } catch (Exception ex) { // Log the error and update the status to indicate failure Console.WriteLine($"Error processing file {result.OutputFilePath}: {ex.Message}"); result.Status = Status.Failed.ToString(); } } return results; } } }