using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace RuriLib.Models
{
///
/// Represents a data line that needs to be checked.
///
public class CData
{
/// The actual content of the line.
public string Data { get; set; }
/// The WordlistType of the Wordlist the line belongs to.
public WordlistType Type { get; set; }
/// Whether the data line respects the regex verification.
public bool IsValid
{
get
{
if (Type.Verify) return Regex.Match(Data, Type.Regex).Success;
else return true;
}
}
///
/// Creates a CData object given a data line and the WordlistType.
///
/// The data line
/// The WordlistType of the Wordlist the data line belongs to
public CData(string data, WordlistType type)
{
Data = data;
Type = type;
}
///
/// Gets all the variables that need to be set after slicing the data line.
///
/// The variables that need to be set inside the Bot's VariableList
public List GetVariables()
{
return Data
.Split(new string[] { Type.Separator }, StringSplitOptions.None)
.Zip(Type.Slices, (k, v) => new { k, v })
.Select(x => new CVar(x.v, x.k, false, true))
.ToList();
}
///
/// Checks if the data line respects all the data rules present in a Config.
///
/// The list of rules of the Config
/// Whether the data line respects the rules
public bool RespectsRules(List rules)
{
var valid = true;
var variables = GetVariables();
foreach(var rule in rules)
{
try
{
var slice = (string)variables.FirstOrDefault(v => v.Name == rule.SliceName).Value;
switch (rule.RuleType)
{
case RuleType.MinLength:
valid = slice.Length >= int.Parse(rule.RuleString);
break;
case RuleType.MaxLength:
valid = slice.Length <= int.Parse(rule.RuleString);
break;
case RuleType.MustContain:
valid = CheckContains(slice, rule.RuleString);
break;
case RuleType.MustNotContain:
valid = !CheckContains(slice, rule.RuleString);
break;
}
if (!valid) return false;
}
catch { }
}
return true;
}
///
/// Checks if a data line contains certain characters.
///
/// The data line
/// The characters to search. Defaults are Lowercase, Uppercase, Digit, Symbol. Custom character sets can be created by concatenating the characters in a single string (e.g. ABCDEF)
///
private static bool CheckContains(string input, string what)
{
switch (what)
{
case "Lowercase":
return input.Any(c => char.IsLower(c));
case "Uppercase":
return input.Any(c => char.IsUpper(c));
case "Digit":
return input.Any(c => char.IsDigit(c));
case "Symbol":
return input.Any(c => char.IsSymbol(c));
default:
foreach(var c in what.ToCharArray())
{
if (input.Contains(c)) return true;
}
return false;
}
}
}
}