namespace ScreenJob.WindowsServiceHost; internal sealed record ServiceOptions( string BackendScriptPath, string WorkingDirectory, string LogDirectory) { public static ServiceOptions Parse(string[] args) { var map = new Dictionary(StringComparer.OrdinalIgnoreCase); for (var i = 0; i < args.Length; i++) { var raw = args[i]; if (!raw.StartsWith("--", StringComparison.Ordinal)) { continue; } var key = raw[2..]; if (string.IsNullOrWhiteSpace(key)) { continue; } if (i + 1 < args.Length && !args[i + 1].StartsWith("--", StringComparison.Ordinal)) { map[key] = args[++i]; } else { map[key] = "true"; } } if (!map.TryGetValue("backend-script", out var backendScript) || string.IsNullOrWhiteSpace(backendScript)) { throw new ArgumentException("Missing required argument: --backend-script ."); } if (!Path.IsPathRooted(backendScript)) { throw new ArgumentException("The --backend-script value must be an absolute path."); } if (!File.Exists(backendScript)) { throw new FileNotFoundException("Backend script not found.", backendScript); } if (!map.TryGetValue("working-dir", out var workingDir) || string.IsNullOrWhiteSpace(workingDir)) { workingDir = Path.GetDirectoryName(backendScript) ?? throw new ArgumentException("Could not resolve working directory from backend script path."); } if (!Path.IsPathRooted(workingDir)) { throw new ArgumentException("The --working-dir value must be an absolute path."); } if (!map.TryGetValue("log-dir", out var logDir) || string.IsNullOrWhiteSpace(logDir)) { logDir = Path.Combine(workingDir, "screenjob_runs", "service"); } if (!Path.IsPathRooted(logDir)) { throw new ArgumentException("The --log-dir value must be an absolute path."); } return new ServiceOptions( Path.GetFullPath(backendScript), Path.GetFullPath(workingDir), Path.GetFullPath(logDir)); } }