private static bool GetSwitchedValue(bool existingValue, SettingSwitch settingSwitch)
 {
     if (settingSwitch == SettingSwitch.Invalid)
     {
         throw new ArgumentException("Cannot change setting for invalid switch", nameof(settingSwitch));
     }
     if (settingSwitch == SettingSwitch.Toggle)
     {
         return(!existingValue);
     }
     if (settingSwitch == SettingSwitch.On)
     {
         return(true);
     }
     if (settingSwitch == SettingSwitch.Off)
     {
         return(false);
     }
     throw new ArgumentException($"Unknown switch type {settingSwitch}", nameof(settingSwitch));
 }
        private async Task CmdPostUrlAsync(CommandContext context, Match regexMatch, CancellationToken cancellationToken = default)
        {
            // if is group, ensure user is admin or owner
            if (context.IsGroup)
            {
                WolfGroupMember member = await GetGroupMemberAsync(context, cancellationToken).ConfigureAwait(false);

                if (member == null)
                {
                    await context.Client.SendGroupMembersBugNoticeAsync(context.Message, cancellationToken).ConfigureAwait(false);

                    return;
                }
                if (member?.HasAdminPrivileges != true)
                {
                    await context.ReplyTextAsync("/alert You need at least admin permissions to change group config.", cancellationToken).ConfigureAwait(false);

                    return;
                }
            }

            // check how the user wants to change the setting
            SettingSwitch settingSwitch = ParseSettingSwitch(regexMatch.Groups.Count > 1 ? regexMatch.Groups[1]?.Value : null);

            if (settingSwitch == SettingSwitch.Invalid)
            {
                await context.ReplyTextAsync("/alert Invalid switch.\r\n" +
                                             "Allowed values: on, true, enable, enabled, off, false, disable, disabled, toggle", cancellationToken).ConfigureAwait(false);

                return;
            }

            // get and update config
            ITargetConfig config = await GetConfigAsync <ITargetConfig>(context.Message, cancellationToken).ConfigureAwait(false);

            config.PostImageURL = GetSwitchedValue(config.PostImageURL, settingSwitch);
            await SaveConfigAsync(config, cancellationToken).ConfigureAwait(false);

            await context.ReplyTextAsync($"/me Posting image URLs {(config.PostImageURL ? "enabled" : "disabled")}.", cancellationToken).ConfigureAwait(false);
        }
        private async Task CmdListenAsync(CommandContext context, Match regexMatch, CancellationToken cancellationToken = default)
        {
            // check user is admin or owner
            string mode = regexMatch.Groups[1]?.Value?.ToLowerInvariant();

            if (!string.IsNullOrEmpty(mode))
            {
                WolfGroupMember member = await GetGroupMemberAsync(context, cancellationToken).ConfigureAwait(false);

                if (member?.HasAdminPrivileges != true)
                {
                    await context.ReplyTextAsync("/alert You need at least admin permissions to change group config.", cancellationToken).ConfigureAwait(false);

                    return;
                }
            }

            // check how the user wants to change the setting
            SettingSwitch settingSwitch = ParseSettingSwitch(regexMatch.Groups.Count > 2 ? regexMatch.Groups[2]?.Value : null);

            if (settingSwitch == SettingSwitch.Invalid)
            {
                await context.ReplyTextAsync("/alert Invalid switch.\r\n" +
                                             "Allowed values: on, true, enable, enabled, off, false, disable, disabled, toggle", cancellationToken).ConfigureAwait(false);

                return;
            }

            // get config
            GroupConfig config = await GetConfigAsync <GroupConfig>(context.Message, cancellationToken).ConfigureAwait(false);

            // change settings based on mode
            switch (mode)
            {
            // if no mode or switch privided, simply list current settings
            case null:
            case "":
                await context.ReplyTextAsync("Current listen mode settings for this group:\r\n" +
                                             $"Admins: {BoolToOnOff(config.ListenAdmins)}\r\n" +
                                             $"Mods: {BoolToOnOff(config.ListenMods)}\r\n" +
                                             $"Users: {BoolToOnOff(config.ListenUsers)}\r\n" +
                                             $"Bots: {BoolToOnOff(config.ListenBots)}\r\n\r\n" +
                                             $"Automatic checking is currently {(config.IsEnabled ? "enabled" : "disabled")}.", cancellationToken).ConfigureAwait(false);

                return;

            // for help, send help message
            case "help":
                await context.ReplyTextAsync("listen <mode> [switch]\r\n" +
                                             "Mode (mandatory): admins, mods, users, bots\r\n" +
                                             "Switch (optional): on, off, toggle", cancellationToken).ConfigureAwait(false);

                return;

            // process each of listen modes
            case "admins":
            case "admin":
                config.ListenAdmins = GetSwitchedValue(config.ListenAdmins, settingSwitch);
                await context.ReplyTextAsync($"/me Listening to admins set to {BoolToOnOff(config.ListenAdmins)} (y)", cancellationToken).ConfigureAwait(false);

                break;

            case "mods":
            case "mod":
                config.ListenMods = GetSwitchedValue(config.ListenMods, settingSwitch);
                await context.ReplyTextAsync($"/me Listening to mods set to {BoolToOnOff(config.ListenMods)} (y)", cancellationToken).ConfigureAwait(false);

                break;

            case "users":
            case "user":
                config.ListenUsers = GetSwitchedValue(config.ListenUsers, settingSwitch);
                await context.ReplyTextAsync($"/me Listening to users without role set to {BoolToOnOff(config.ListenUsers)} (y)", cancellationToken).ConfigureAwait(false);

                break;

            case "bots":
            case "bot":
                config.ListenBots = GetSwitchedValue(config.ListenBots, settingSwitch);
                await context.ReplyTextAsync($"/me Listening to bots set to {BoolToOnOff(config.ListenBots)} (y)", cancellationToken).ConfigureAwait(false);

                break;

            default:
                await context.ReplyTextAsync($"/alert Unknown listening mode: {mode}", cancellationToken).ConfigureAwait(false);

                return;
            }

            // save settings
            await SaveConfigAsync(config, cancellationToken).ConfigureAwait(false);
        }