159 lines
5.6 KiB
C#
159 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
|
|
public enum ConfigType { Bool, Choice, String, ValidatedString }
|
|
|
|
// Delegate signature for custom validation functions
|
|
public delegate (bool IsValid, string? ErrorMessage) ConfigValidator(string input);
|
|
|
|
public class ConfigOption
|
|
{
|
|
public string Id { get; set; }
|
|
public string Description { get; set; }
|
|
public ConfigType Type { get; set; } = ConfigType.Bool;
|
|
public string DefaultValue { get; set; } = "y";
|
|
public List<string> Choices { get; set; } = [];
|
|
public Func<Dictionary<string, string>, bool>? Dependency { get; set; }
|
|
|
|
// Delegate for string validation rules
|
|
public ConfigValidator? Validator { get; set; }
|
|
|
|
public ConfigOption()
|
|
{
|
|
}
|
|
|
|
public ConfigOption(string id, string description, ConfigType type, string defaultValue)
|
|
{
|
|
Id = id;
|
|
Description = description;
|
|
Type = type;
|
|
DefaultValue = defaultValue;
|
|
}
|
|
|
|
public void SetChoices(params string[] args)
|
|
{
|
|
Choices = new List<string>(args);
|
|
}
|
|
}
|
|
|
|
public class OldConfigEngine
|
|
{
|
|
private readonly List<ConfigOption> _schema = [];
|
|
private readonly Dictionary<string, string> _currentConfig = [];
|
|
|
|
public void RegisterOption(ConfigOption option) => _schema.Add(option);
|
|
|
|
public void LoadExistingConfig(string filePath)
|
|
{
|
|
if (!File.Exists(filePath)) return;
|
|
foreach (var line in File.ReadAllLines(filePath))
|
|
{
|
|
var trimmed = line.Trim();
|
|
if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith("#")) continue;
|
|
var parts = trimmed.Split('=', 2);
|
|
if (parts.Length == 2) _currentConfig[parts[0].Trim()] = parts[1].Trim();
|
|
}
|
|
}
|
|
|
|
public void RunInteractiveConfig()
|
|
{
|
|
Console.WriteLine("*");
|
|
Console.WriteLine("* Restart config based on current configuration");
|
|
Console.WriteLine("*");
|
|
|
|
foreach (var opt in _schema)
|
|
{
|
|
if (opt.Dependency != null && !opt.Dependency(_currentConfig))
|
|
continue;
|
|
|
|
if (_currentConfig.ContainsKey(opt.Id))
|
|
continue;
|
|
|
|
string selectedValue = PromptUser(opt);
|
|
_currentConfig[opt.Id] = selectedValue;
|
|
}
|
|
|
|
Console.WriteLine("\n*** End of configuration. ***");
|
|
}
|
|
|
|
public string PromptUser(ConfigOption opt)
|
|
{
|
|
while (true)
|
|
{
|
|
switch (opt.Type)
|
|
{
|
|
case ConfigType.Bool:
|
|
string choicesHint = opt.DefaultValue.ToLower() == "y" ? "[Y/n]" : "[y/N]";
|
|
Console.Write($"{opt.Description} ({opt.Id}) {choicesHint} ");
|
|
|
|
var key = Console.ReadKey(intercept: false);
|
|
Console.WriteLine();
|
|
|
|
if (key.Key == ConsoleKey.Enter)
|
|
return opt.DefaultValue;
|
|
if (key.Key == ConsoleKey.Y)
|
|
return "true";
|
|
if (key.Key == ConsoleKey.N)
|
|
return "false";
|
|
if (key.Key == ConsoleKey.Q || key.KeyChar == '?')
|
|
{
|
|
Console.WriteLine($" Help: Toggles option {opt.Id}. Select Y or N.");
|
|
continue;
|
|
}
|
|
break;
|
|
|
|
case ConfigType.Choice:
|
|
Console.WriteLine($"{opt.Description} ({opt.Id})");
|
|
for (int i = 0; i < opt.Choices.Count; i++)
|
|
{
|
|
string marker = opt.Choices[i] == opt.DefaultValue ? " (NEW)" : "";
|
|
Console.WriteLine($" {i + 1}. {opt.Choices[i]}{marker}");
|
|
}
|
|
Console.Write($"choice[1-{opt.Choices.Count}]: ");
|
|
|
|
string? choiceInput = Console.ReadLine()?.Trim();
|
|
if (string.IsNullOrEmpty(choiceInput)) return opt.DefaultValue;
|
|
if (int.TryParse(choiceInput, out int idx) && idx >= 1 && idx <= opt.Choices.Count)
|
|
{
|
|
return opt.Choices[idx - 1];
|
|
}
|
|
break;
|
|
|
|
case ConfigType.String:
|
|
Console.Write($"{opt.Description} ({opt.Id}) [{opt.DefaultValue}]: ");
|
|
string? strInput = Console.ReadLine()?.Trim();
|
|
return string.IsNullOrEmpty(strInput) ? opt.DefaultValue : strInput;
|
|
|
|
case ConfigType.ValidatedString:
|
|
Console.Write($"{opt.Description} ({opt.Id}) [{opt.DefaultValue}]: ");
|
|
string rawVal = Console.ReadLine()?.Trim() ?? string.Empty;
|
|
string valueToValidate = string.IsNullOrEmpty(rawVal) ? opt.DefaultValue : rawVal;
|
|
|
|
if (opt.Validator != null)
|
|
{
|
|
var (isValid, errorMessage) = opt.Validator(valueToValidate);
|
|
if (!isValid)
|
|
{
|
|
Console.WriteLine($" [Error] {errorMessage ?? "Invalid value provided."}");
|
|
continue; // Re-prompt on validation failure
|
|
}
|
|
}
|
|
|
|
return valueToValidate;
|
|
}
|
|
|
|
Console.WriteLine("Invalid choice. Try again.");
|
|
}
|
|
}
|
|
|
|
public void SaveConfig(string filePath)
|
|
{
|
|
using var writer = new StreamWriter(filePath);
|
|
writer.WriteLine($"# Automatically generated config - {DateTime.UtcNow:u}");
|
|
foreach (var kvp in _currentConfig)
|
|
{
|
|
writer.WriteLine($"{kvp.Key}={kvp.Value}");
|
|
}
|
|
}
|
|
} |