using LAPS_XMLQC_Service.Models; using LAPS_XMLQC_Service.Services; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Threading; using System.IO; using Microsoft.AspNetCore.Authorization; namespace LAPS_XMLQC_Service.Controllers.RegexReplace { [Route("api/[controller]")] [ApiController] public class RegexReplaceApiController : ControllerBase { private readonly RegexPatternService _regexPatternService; private readonly FileSearchService _fileSearchService; public RegexReplaceApiController(RegexPatternService regexPatternService, FileSearchService fileSearchService) { _regexPatternService = regexPatternService; _fileSearchService = fileSearchService; } [Authorize] [HttpGet("GetPatterns")] public IActionResult GetPatterns() { var patterns = _regexPatternService.GetRegexPatterns(); return Ok(patterns); } [Authorize] [HttpPost("Search")] public async Task PerformSearch([FromBody] SearchRequest request) { var results = await _fileSearchService.SearchFiles(request.DirectoryPath, request.SearchTerm, request.FileType, request.CaseInsensitive, request.SingleLine, request.MultiLine, request.IgnoreWhitespace, request.ExplicitCapture); return Ok(results); } [Authorize] [HttpPost("Preview")] public async Task PreviewChanges([FromBody] SearchRequest request) { var results = await _fileSearchService.PreviewOrReplaceAll(request.DirectoryPath, request.SearchTerm, request.ReplacementText, request.FileType, request.CaseInsensitive, request.SingleLine, request.MultiLine, request.IgnoreWhitespace, request.ExplicitCapture, "Preview"); return Ok(results); } [Authorize] [HttpPost("ReplaceAll")] public async Task ReplaceAllChanges([FromBody] SearchRequest request) { var results = await _fileSearchService.PreviewOrReplaceAll(request.DirectoryPath, request.SearchTerm, request.ReplacementText, request.FileType, request.CaseInsensitive, request.SingleLine, request.MultiLine, request.IgnoreWhitespace, request.ExplicitCapture, "ReplaceAll"); return Ok(results); } [Authorize] [HttpPost("Apply")] public async Task ApplyChanges([FromBody] MatchedResult results) { if (results == null) { return BadRequest("No changes provided to apply."); } try { results = await _fileSearchService.ApplyChange(results); return Ok(results); } catch (Exception ex) { return StatusCode(500, $"An error occurred while applying changes: {ex.Message}"); } } [Authorize] [HttpPost("Accept")] public IActionResult Accept([FromBody] List results) { if (results == null) { return BadRequest("No changes provided to apply."); } try { results = _fileSearchService.Accept(results); return Ok(results); } catch (Exception ex) { return StatusCode(500, $"An error occurred while applying changes: {ex.Message}"); } } [Authorize] [HttpPost("Reject")] public IActionResult Reject([FromBody] List results) { if (results == null) { return BadRequest("No changes provided to apply."); } try { results = _fileSearchService.Reject(results); return Ok(results); } catch (Exception ex) { return StatusCode(500, $"An error occurred while applying changes: {ex.Message}"); } } [Authorize] [HttpPost("Upload")] public async Task UploadFiles([FromForm] UploadRequest request) { var results = new List(); if (request?.Files == null || request.Files.Count == 0) { return BadRequest("No files were uploaded."); } string fileExtension = request.FileType.Replace("*", string.Empty); if (string.IsNullOrWhiteSpace(fileExtension)) { return BadRequest("Invalid file type specified."); } // Limit the number of concurrent tasks int maxDegreeOfParallelism = 5; // Adjust this value based on your server's capabilities var semaphore = new SemaphoreSlim(maxDegreeOfParallelism); var tasks = request.Files.Select(async file => { await semaphore.WaitAsync(); // Limit concurrent execution try { // Check if the file's extension matches the requested file type if (!Path.GetExtension(file.FileName).Equals(fileExtension, StringComparison.OrdinalIgnoreCase)) { return null; // Skip files that don't match the extension } using var stream = new MemoryStream(); await file.CopyToAsync(stream); var content = System.Text.Encoding.UTF8.GetString(stream.ToArray()); // Perform regex search on the file content var matches = await _fileSearchService.SearchContent(content, request.SearchTerm, request.CaseInsensitive, request.SingleLine, request.MultiLine, request.IgnoreWhitespace, request.ExplicitCapture); // Calculate the total result count across all pattern results int resultCount = matches.Sum(patternResult => patternResult.Matches!.Count); return new MatchedResult { FileName = file.FileName, Content = content, PatternResults = matches, ResultCount = resultCount }; } catch { // Log the error (or handle it as needed) // Return null to indicate an error for this file return null; } finally { semaphore.Release(); // Release the semaphore for the next task } }); // Await all the tasks and filter out any null results var taskResults = await Task.WhenAll(tasks); results = taskResults.Where(result => result != null).Cast().ToList(); return Ok(results); } } }