1 module diggler.defaultcommands;
2 
3 import diggler.attribute;
4 import diggler.bot;
5 import diggler.context;
6 import diggler.command;
7 
8 final class DefaultCommands : ICommandSet
9 {
10 	Bot bot;
11 	Context _context;
12 	alias _context this;
13 	Command helpCommand;
14 
15 	this(Bot bot)
16 	{
17 		this.bot = bot;
18 		this.helpCommand = Command.create!help(&help);
19 	}
20 
21 	@usage("show usage information for commands.")
22 	void help(string commandName = null)
23 	{
24 		import std.array;
25 		import std.algorithm : filter, map, joiner, reduce;
26 		import std.range : chain;
27 		import irc.util : values;
28 		import diggler.util : pluralize;
29 
30 		if(commandName.empty)
31 		{
32 			auto namedSets = bot.commandSets.filter!(set => set.category);
33 
34 			foreach(cmdSet; namedSets)
35 			{
36 				string[] commands = cmdSet.commandNames;
37 				if(!commands.empty)
38 				{
39 					auto commandList = commands.joiner(", ");
40 					reply(`%s %s %s: %s`, commands.length, cmdSet.category, pluralize!"command"(commands.length), commandList);
41 				}
42 			}
43 
44 			auto miscCommands = bot.commandSets
45 				.filter!(set => !set.category)
46 				.map!(set => cast(string[])set.commandNames);
47 
48 			auto numCommands = reduce!((sum, cmds) => sum + cmds.length)(0UL, miscCommands);
49 
50 			if(numCommands != 0)
51 			{
52 				auto disambiguation = namedSets.empty? "" : "miscellaneous ";
53 				reply("%s %s%s: %s", numCommands, disambiguation, pluralize!"command"(numCommands), miscCommands.joiner().joiner(", "));
54 			}
55 		}
56 		else
57 		{
58 			foreach(cmdSet; bot.commandSets)
59 			{
60 				if(auto cmd = cmdSet.getCommand(commandName))
61 				{
62 					auto names = values(cmd.name)
63 						.chain(cmd.aliases)
64 						.joiner("|");
65 
66 					auto paramSummary =
67 						cmd.parameterInfo.map!(param => param.displayName)
68 						.joiner(" ");
69 
70 					immutable description = cmd.usage? cmd.usage : "no description available.";
71 
72 					string flags;
73 					if(cmd.channelOnly && cmd.adminOnly)
74 						flags = " [channel, admin]";
75 					else if(cmd.channelOnly)
76 						flags = " [channel]";
77 					else if(cmd.adminOnly)
78 						flags = " [admin]";
79 					else
80 						flags = "";
81 
82 					reply(`%s %s: %s%s`, names, paramSummary, description, flags);
83 
84 					return; // Shouldn't be any duplicates
85 				}
86 			}
87 
88 			reply(`The command "%s" does not appear to exist.`, commandName);
89 		}
90 	}
91 
92 	override string category()
93 	{
94 		return null;
95 	}
96 
97 	override ref Context context()
98 	{
99 		return _context;
100 	}
101 
102 	override void add(ref Command) {}
103 
104 	override Command* getCommand(in char[] name)
105 	{
106 		return name == "help"? &helpCommand : null;
107 	}
108 
109 	override string[] commandNames()
110 	{
111 		return null;
112 	}
113 }