discord-bot/CompatBot/Commands/AutoCompleteProviders/BotConfigurationAutoCompleteProvider.cs

60 lines
2.3 KiB
C#

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<string> KnownConfigVariables = typeof(Config)
.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.ExactBinding)
.Select(pi => pi.Name)
.OrderBy(n => n)
.ToList();
public async ValueTask<IEnumerable<DiscordAutoCompleteChoice>> 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<string> 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();
}
}