namespace AcDream.Headless.Configuration; internal sealed record HeadlessCommandLine( string Command, string ConfigurationPath, HeadlessPathOverrides Paths, HeadlessDirectCredentials? DirectCredentials) { internal static HeadlessCommandLine Parse( IReadOnlyList arguments) { ArgumentNullException.ThrowIfNull(arguments); if (arguments.Count < 3) throw new HeadlessCommandLineException("Missing command options."); string command = arguments[0]; if (command is not ("validate" or "run")) throw new HeadlessCommandLineException("Unknown command."); string? configurationPath = null; string? configDirectory = null; string? dataDirectory = null; string? cacheDirectory = null; string? user = null; string? password = null; for (int index = 1; index < arguments.Count; index += 2) { if (index + 1 >= arguments.Count) { throw new HeadlessCommandLineException( "Every command option requires a value."); } string name = arguments[index]; string value = arguments[index + 1]; if (string.IsNullOrWhiteSpace(value)) { throw new HeadlessCommandLineException( "Command option values cannot be empty."); } switch (name) { case "--config": SetOnce(ref configurationPath, value); break; case "--config-dir": SetOnce(ref configDirectory, value); break; case "--data-dir": SetOnce(ref dataDirectory, value); break; case "--cache-dir": SetOnce(ref cacheDirectory, value); break; case "-user": case "--user": SetOnce(ref user, value); break; case "-password": case "--password": SetOnce(ref password, value); break; default: throw new HeadlessCommandLineException( "Unknown command option."); } } if (configurationPath is null) { throw new HeadlessCommandLineException( "The --config option is required."); } if ((user is null) != (password is null)) { throw new HeadlessCommandLineException( "The user and password options must be supplied together."); } if (user is not null && command != "run") { throw new HeadlessCommandLineException( "Direct credentials are valid only for run mode."); } return new HeadlessCommandLine( command, configurationPath, new HeadlessPathOverrides( configDirectory, dataDirectory, cacheDirectory), user is null ? null : new HeadlessDirectCredentials(user, password!)); } private static void SetOnce(ref string? destination, string value) { if (destination is not null) { throw new HeadlessCommandLineException( "Command options cannot be repeated."); } destination = value; } } internal sealed record HeadlessDirectCredentials( string User, string Password);