using RobotNet10.CustomConfiguration.Models;
using System.Globalization;
namespace RobotNet10.CustomConfiguration.Validators;
///
/// Validator cho config files và variables
///
public static class ConfigValidator
{
///
/// Validate một config file
///
public static ValidationResult ValidateConfig(ConfigFile config)
{
var errors = new List();
// Validate ConfigType
if (string.IsNullOrWhiteSpace(config.ConfigType))
{
errors.Add("ConfigType cannot be empty");
}
// Validate Variables
if (config.Variables != null && config.Variables.Count > 0)
{
foreach (var variable in config.Variables)
{
var variableErrors = ValidateVariable(variable);
errors.AddRange(variableErrors);
}
}
return new ValidationResult
{
IsValid = errors.Count == 0,
Errors = errors
};
}
///
/// Validate một variable
///
public static List ValidateVariable(ConfigVariable variable)
{
var errors = new List();
// Validate Name
if (string.IsNullOrWhiteSpace(variable.Name))
{
errors.Add("Variable name cannot be empty");
}
// Validate Type
if (!Enum.IsDefined(variable.Type))
{
errors.Add($"Invalid variable type: {variable.Type}");
}
// Validate Value theo Type
if (variable.Value == null)
{
errors.Add($"Variable '{variable.Name}' value cannot be null");
}
else
{
var valueErrors = ValidateValueByType(variable.Name, variable.Type, variable.Value, variable.Min, variable.Max, variable);
errors.AddRange(valueErrors);
}
return errors;
}
///
/// Validate value theo type và Min/Max constraints
///
private static List ValidateValueByType(string variableName, ConfigVariableType type, object value, double? min, double? max, ConfigVariable? variable = null)
{
var errors = new List();
switch (type)
{
case ConfigVariableType.Int:
// Try parse
if (int.TryParse(value.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedInt))
{
if (min.HasValue && parsedInt < min.Value)
errors.Add($"Variable '{variableName}' value {parsedInt} is less than Min {min.Value}");
if (max.HasValue && parsedInt > max.Value)
errors.Add($"Variable '{variableName}' value {parsedInt} is greater than Max {max.Value}");
}
else
{
errors.Add($"Variable '{variableName}' must be an integer");
}
break;
case ConfigVariableType.Double:
// Try parse
if (double.TryParse(value.ToString(), NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out var parsedDouble))
{
if (min.HasValue && parsedDouble < min.Value)
errors.Add($"Variable '{variableName}' value {parsedDouble} is less than Min {min.Value}");
if (max.HasValue && parsedDouble > max.Value)
errors.Add($"Variable '{variableName}' value {parsedDouble} is greater than Max {max.Value}");
}
else
{
errors.Add($"Variable '{variableName}' must be a double");
}
break;
case ConfigVariableType.Bool:
if (!bool.TryParse(value.ToString(), out _))
{
errors.Add($"Variable '{variableName}' must be a boolean");
}
break;
case ConfigVariableType.Object:
// Object có thể là Dictionary hoặc JsonElement
if (value is not Dictionary &&
value is not System.Text.Json.JsonElement)
{
// Try parse as JSON object
try
{
var jsonString = value.ToString();
if (jsonString != null)
{
using var doc = System.Text.Json.JsonDocument.Parse(jsonString);
if (doc.RootElement.ValueKind != System.Text.Json.JsonValueKind.Object)
{
errors.Add($"Variable '{variableName}' must be a JSON object");
}
}
}
catch (System.Text.Json.JsonException)
{
errors.Add($"Variable '{variableName}' must be a valid JSON object");
}
}
break;
case ConfigVariableType.Array:
// Array có thể là List