using System.Linq; using System.Threading.Tasks; using Myriad.Extensions; using Myriad.Rest.Types; using PluralKit.Core; namespace PluralKit.Bot { public class SystemLink { private readonly IDatabase _db; private readonly ModelRepository _repo; public SystemLink(IDatabase db, ModelRepository repo) { _db = db; _repo = repo; } public async Task LinkSystem(Context ctx) { ctx.CheckSystem(); await using var conn = await _db.Obtain(); var account = await ctx.MatchUser() ?? throw new PKSyntaxError("You must pass an account to link with (either ID or @mention)."); var accountIds = await _repo.GetSystemAccounts(conn, ctx.System.Id); if (accountIds.Contains(account.Id)) throw Errors.AccountAlreadyLinked; var existingAccount = await _repo.GetSystemByAccount(conn, account.Id); if (existingAccount != null) throw Errors.AccountInOtherSystem(existingAccount); var msg = $"{account.Mention()}, please confirm the link by clicking the {Emojis.Success} reaction on this message."; var mentions = new AllowedMentions {Users = new[] {account.Id}}; if (!await ctx.PromptYesNo(msg, user: account, mentions: mentions, matchFlag: false)) throw Errors.MemberLinkCancelled; await _repo.AddAccount(conn, ctx.System.Id, account.Id); await ctx.Reply($"{Emojis.Success} Account linked to system."); } public async Task UnlinkAccount(Context ctx) { ctx.CheckSystem(); await using var conn = await _db.Obtain(); ulong id; if (!ctx.HasNext()) id = ctx.Author.Id; else if (!ctx.MatchUserRaw(out id)) throw new PKSyntaxError("You must pass an account to link with (either ID or @mention)."); var accountIds = (await _repo.GetSystemAccounts(conn, ctx.System.Id)).ToList(); if (!accountIds.Contains(id)) throw Errors.AccountNotLinked; if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount; var msg = $"Are you sure you want to unlink <@{id}> from your system?"; if (!await ctx.PromptYesNo(msg)) throw Errors.MemberUnlinkCancelled; await _repo.RemoveAccount(conn, ctx.System.Id, id); await ctx.Reply($"{Emojis.Success} Account unlinked."); } } }