using System.Reflection; using CompatApiClient.Utils; using CompatBot.Database; using CompatBot.Database.Providers; using Microsoft.EntityFrameworkCore; namespace CompatBot.Commands.AutoCompleteProviders; public class BotConfigurationAutoCompleteProvider: IAutoCompleteProvider { private static readonly List KnownConfigVariables = typeof(Config) .GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.ExactBinding) .Select(pi => pi.Name) .OrderBy(n => n) .ToList(); public async ValueTask> AutoCompleteAsync(AutoCompleteContext context) { if (!ModProvider.IsSudoer(context.User.Id)) return [new($"{Config.Reactions.Denied} You are not authorized to use this command.", -1)]; await using var db = await BotDb.OpenReadAsync().ConfigureAwait(false); IEnumerable result; var input = context.UserInput; if (input is not { Length: > 0 }) { var set = db.BotState .AsNoTracking() .Where(v => v.Key.StartsWith(SqlConfiguration.ConfigVarPrefix)) .OrderBy(v => v.Key) .Take(25) .Select(v => v.Key) .AsEnumerable() .Select(k => k[SqlConfiguration.ConfigVarPrefix.Length ..]); result = set.Concat(KnownConfigVariables); } else { var prefix = KnownConfigVariables .Where(n => n.StartsWith(input, StringComparison.OrdinalIgnoreCase)) .Take(25); var sub = KnownConfigVariables .Where(n => n.Contains(input, StringComparison.OrdinalIgnoreCase)) .Take(50); var fuzzy = KnownConfigVariables .Select(n => new { coef = n.GetFuzzyCoefficientCached(input), val = n }) .Where(i => i.coef > 0.5) .OrderByDescending(i => i.coef) .Take(25) .Select(i => i.val); result = prefix .Concat(sub) .Concat(fuzzy); } return result .Distinct() .Take(25) .Select(n => new DiscordAutoCompleteChoice(n.Trim(100), n)).ToList(); } }