using System.Diagnostics; namespace LiquidCode.Tester.Worker.Services; public class CppCompilationService : ICompilationService { private readonly ILogger _logger; private readonly IConfiguration _configuration; public CppCompilationService(ILogger logger, IConfiguration configuration) { _logger = logger; _configuration = configuration; } public async Task CompileAsync(string sourceCode, string workingDirectory) { var sourceFilePath = Path.Combine(workingDirectory, "solution.cpp"); var executablePath = Path.Combine(workingDirectory, "solution"); _logger.LogInformation("Compiling C++ code in {WorkingDirectory}", workingDirectory); try { // Write source code to file await File.WriteAllTextAsync(sourceFilePath, sourceCode); // Compile using g++ var compiler = _configuration["Cpp:Compiler"] ?? "g++"; var compilerFlags = _configuration["Cpp:CompilerFlags"] ?? "-O2 -std=c++17 -Wall"; var process = new Process { StartInfo = new ProcessStartInfo { FileName = compiler, Arguments = $"{compilerFlags} {sourceFilePath} -o {executablePath}", WorkingDirectory = workingDirectory, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true } }; process.Start(); var output = await process.StandardOutput.ReadToEndAsync(); var error = await process.StandardError.ReadToEndAsync(); await process.WaitForExitAsync(); var compilerOutput = $"{output}\n{error}".Trim(); if (process.ExitCode == 0 && File.Exists(executablePath)) { _logger.LogInformation("Compilation successful"); return new CompilationResult { Success = true, ExecutablePath = executablePath, CompilerOutput = compilerOutput }; } else { _logger.LogWarning("Compilation failed with exit code {ExitCode}", process.ExitCode); return new CompilationResult { Success = false, ErrorMessage = "Compilation failed", CompilerOutput = compilerOutput }; } } catch (Exception ex) { _logger.LogError(ex, "Error during compilation"); return new CompilationResult { Success = false, ErrorMessage = $"Compilation error: {ex.Message}" }; } } }