#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "general.H"
#include "cli.H"
#include "x10map.H"

#define COND_UNKNOWN	0
#define COND_AT		7
#define COND_BELOW	8
#define COND_ABOVE	9


TOKEN_TABLE x10flags [] = {
	{ XS_EXIST,	"exist" },
	{ XS_TWOWAY,	"twoway" },
	{ XS_ALIVE,	"alive" },
	{ XS_LIGHT,	"light" },
	{ XS_ON,	"on" },
	{ XS_ME,	"me" },
	{ XS_UPONLY,	"uponly" },
	{ XS_DOWNONLY,	"downonly" },
	{ 0,		NULL }
};


TOKEN_TABLE tests [] = {
	{ COND_AT,	"at" },
	{ COND_BELOW,	"below" },
	{ COND_ABOVE,	"above" },
	{ COND_UNKNOWN, NULL }
};


int x10test (int housecode, int unit, char **argv)
{
	struct x10state state;

	if (!unit)
		return (FAIL_UNITNEEDED);

	int status = mapX10state (housecode, unit, &state);
	if (status != SUCCESS)
		return (status);

	char *test = *(argv++);
	if (!test) {
		fprintf (stderr, "%s: Test condition must be specified.\n",
			program_name);
		return (FAIL_PARSE);
	}

	int flags;
	if (flags = get_token (test, x10flags)) {
		if (debug_level)
			fprintf (stderr, "flags=%d\n", flags);
		return (!(state.flags & flags));
	}

	if (!*argv) {
		fprintf (stderr, "%s: Value must be specified for test %s.\n",
			program_name, test);
		return (FAIL_PARSE);
	}

	char *error;
	int level;
	level = strtol (*argv, &error, 10);
	if ((error && *error && strcmp (error, "%") != 0)
			|| level < 0 || level > 100) {
		fprintf (stderr, "%s: Invalid comparison level.\n",
			program_name, *argv);
		return (FAIL_PARSE);
	}

	level /= 5;
	switch (get_token (test, tests)) {
		case COND_AT:     return !(state.level == level);
		case COND_BELOW:  return !(state.level < level);
		case COND_ABOVE:  return !(state.level > level);
	}
	fprintf (stderr, "%s: Unknown test '%s'.\n",
		program_name, test);
	return FAIL_PARSE;
}

