using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; using Terius.Automate.Agent.Models; namespace Terius.Automate.Agent.Services; public sealed class JobExecutor { public async Task ExecuteAsync(JobDefinition job, Action progress, CancellationToken cancellationToken) { var messages = new List(); if (job.Definition.Count == 0) { return new ExecutionResult(false, messages, "La automatización no contiene acciones."); } for (var index = 0; index < job.Definition.Count; index++) { var step = job.Definition[index]; cancellationToken.ThrowIfCancellationRequested(); progress($"Paso {index + 1}/{job.Definition.Count}: {GetStepName(step.Type)}"); switch (step.Type.Trim().ToLowerInvariant()) { case "open_url": ExecuteOpenUrl(step.Url); messages.Add($"URL abierta: {step.Url}"); progress($"URL abierta: {step.Url}"); break; case "wait": var milliseconds = Math.Clamp(step.Milliseconds ?? 1000, 100, 300000); progress($"Esperando {milliseconds} ms…"); await Task.Delay(milliseconds, cancellationToken); messages.Add($"Espera completada: {milliseconds} ms"); break; case "run_program": ExecuteProgram(step.Path); messages.Add($"Programa abierto: {step.Path}"); progress($"Programa abierto: {step.Path}"); break; default: return new ExecutionResult(false, messages, $"Acción no soportada: {step.Type}"); } } return new ExecutionResult(true, messages); } private static string GetStepName(string type) => type.Trim().ToLowerInvariant() switch { "open_url" => "Abrir URL", "wait" => "Esperar", "run_program" => "Abrir programa", _ => type, }; private static void ExecuteOpenUrl(string? value) { if (!Uri.TryCreate(value, UriKind.Absolute, out var uri) || (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)) { throw new InvalidOperationException("La acción open_url contiene una URL inválida."); } Process.Start(new ProcessStartInfo(uri.AbsoluteUri) { UseShellExecute = true }); } private static void ExecuteProgram(string? value) { var path = value?.Trim() ?? string.Empty; if (!Path.IsPathFullyQualified(path) || !File.Exists(path)) { throw new InvalidOperationException($"No se encontró el programa: {path}"); } Process.Start(new ProcessStartInfo(path) { UseShellExecute = true }); } }