#ifndef __KEY_GROUPS__H__
#define __KEY_GROUPS__H__

#include <map>
#include <set>

#include <ncurses.h>

using namespace std;

/* Groups different keystokes. Used in fuzz testing to generate random
 * appropriate keys strokes. Can be used to test if a keycode has a particular
 * property */
class KeyGroups {
public:
	/* random key in the typing line state */
	static int random_type() {
                static vector<int> _choices = {
                        '\n', '\n','\n',
                        'a', 'b', 'c', 'd', 'e', 'f', 'g',
                        '0', '1', '2', '3', '4', '5', '6',
                };
		if (rand() % 2) return random_direction();
                return _choices[rand() % _choices.size()];
	}

	/* random key in the command mode state */
	static int random_action() {
		static vector<int> _choices = {
		        ':', '/', '#', 'e', '^', '$', '\\', '\n',
                        'i', 'f', '!', '\b', 'b', 27, '%', 'C', '<',
			't', 'm', 'T',
                        'c', '>', '*', 'p', 'n', 'B', 'd', '-', '+', 551, 556,
                        336, 337, 'q', KEY_UP, KEY_DOWN, KEY_LEFT,
                        KEY_RIGHT, KEY_PPAGE, KEY_NPAGE, KEY_HOME, KEY_END,
                        KEY_SHOME, KEY_SEND};
                return _choices[rand() % _choices.size()];
	}

	/* random direction keystroke */
	static int random_direction() {
		static vector<int> _choices = {
                        336, 337, KEY_UP, KEY_DOWN, KEY_LEFT,
                        KEY_RIGHT, KEY_PPAGE, KEY_NPAGE,
			KEY_HOME, KEY_END,
                        KEY_SHOME, KEY_SEND};
                return _choices[rand() % _choices.size()];
	}

	/* set of commands that work on a line, to skip if navigation is at end
	 * or lines are empty */
	static bool requires_line(int ch) {
		static set<int> _keys = {
			'#', 'e', 's', 'i', 'f', 'F', 'y',
			'b', '\n', '*', 'p', 'd', 'B'};
		return _keys.count(ch);
	}
};

#endif  // __KEY_GROUPS__H__
