/************************************************************
 *
 * COPYRIGHT (C) HITACHI,LTD. 2002-2003 ALL RIGHTS RESERVED.
 * WRITTEN BY HITACHI SYSTEMS DEVELOPMENT LABORATORY,
 *            HITACHI CENTRAL RESEARCH LABORATORY.
 *
 * Created by K.Hatasaki <keisukeh@crl.hitachi.co.jp>
 * Updated by M.Hiramatsu <hiramatu@sdl.hitachi.co.jp>
 *
 ************************************************************/

#include <stdlib.h>
#include "command.h"
#include "maskset.h"

#define NAME	"lkstm"
#define VERSION "1.4"

void usage(void);

void call_usage(int* , char**);
void call_version(int*, char**);
void call_all(int*, char**);
void call_list(int*, char**);
void call_del(int*, char**);
void call_read(int*, char**);
void call_set(int*, char**);
void call_write(int*, char**);
void call_getid(int*, char**);
void call_config(int*, char**);

int main(int argc, char **argv)
{
	int i;
#define NR_CMD_MAX 255
	struct command cmd[] = 
	{
		[0] = {"help", &call_usage},
		[1] = {"ver", &call_version},
		[2] = {"version", &call_version},
		[3] = {"all", &call_all},
		[4] = {"list", &call_list},
		[5] = {"ls", &call_list},
		[6] = {"delete", &call_del},
		[7] = {"del", &call_del},
		[8] = {"read", &call_read},
		[9] = {"set", &call_set},
		[10] = {"write", &call_write},
		[11] = {"find", &call_getid},
		[12] = {"config", &call_config},
		[13] = {"conf", &call_config},
		[14] = {0, 0},
	};

	if (argc == 1) { /* no command */
		usage();
	} else {
		for (i = 0; cmd[i].name != NULL ; i++) {
			if (!strcmp(cmd[i].name, argv[1])) {
				cmd[i].func(&argc, argv);
				return 0;
			}
		}
		badcommand(argv[1]);
	}
	exit(0);
}


void usage(void)
{
	printf("This controls masksets.\n");
	printf("Usage:\n\t%s command [option(s)]\n\n", NAME);
	printf("<COMMAND>\n");
	printf("all\t\tOutput a list of masksets and display content of all masksets.\n");
	printf("list/ls\t\tOutput a list of all masksets.\n");
	printf("delete/del\tDelete a maskset.\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t-m maskset_id | -n maskset_name\n");
	printf("read\t\tOutput a content of maskset(s).\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t[-m maskset_id | -n maskset_name] [-A] [-a] [-d]\n");
	printf("set\t\tChange to sepecified maskset.\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t-m maskset_id | -n maskset_name\n");
	printf("write\t\tWrite a new maskset.\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t[-m maskset_id ] [-n maskset_name] [-f file_name] [-S]\n");
	printf("config\t\tconfig a single entry of maskset.\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t[-m maskset_id | -n maskset_name] <event_type> <evhandler_id>\n");
	printf("find\t\tFind the id from the name of a maskset.\n");
	printf("\t\t<OPTION>\n");
	printf("\t\t-n maskset_name\n");
	printf("version/ver\tPrint version of this command.\n");
	printf("help\t\tPrint this message.\n");
	exit(0);
}

char mname[LKST_MASKSET_NAME_LEN+1] = {0};

void call_usage(int *argc, char **argv)
{
	usage();
}

void call_version(int *argc, char **argv)
{
	version(NAME, VERSION);
}

void call_all(int *argc, char **argv)
{
	maskset_list();
	maskset_read_all(0, 0);	/* display name of events */
}

void call_list(int *argc, char **argv)
{
	maskset_list();
}

void call_del(int *argc, char **argv)
{
	int c;
	lkst_maskset_id id = LKST_MASKSET_ID_VOID;

	c = getopt(*argc, argv, "m:n:");

	switch(c) {
	case 'm' :
		id = STR2MID(optarg);
		break;
	case 'n' :
		strncpy(mname,optarg,LKST_MASKSET_NAME_LEN);
		break;
	case -1:
		needopt();
		break;
	default :
		usage();
		break;
	}

	if ( (!mname[0] && (id == LKST_MASKSET_ID_VOID)) || 
	     ( mname[0] && (id != LKST_MASKSET_ID_VOID)) )
		needopt();
	
	maskset_delete(id, mname);
}

void call_config(int *argc, char **argv)
{
	int c, offs=2;
	lkst_maskset_id id = LKST_MASKSET_ID_VOID;
	int event_type;
	int evh_id;
	
	while((c = getopt(*argc, argv, "m:n:")) != EOF) {
		switch(c) {
		case 'm' :
			id = STR2MID(optarg);
			offs += 2;
			break;
		case 'n' :
			strncpy(mname,optarg,LKST_MASKSET_NAME_LEN);
			offs += 2;
			break;
		default:
			;
		}
	}

	if ((mname[0] && id != LKST_MASKSET_ID_VOID) )
		usage();

	if (*argc - offs < 2) 
		needopt();

	event_type = STR2ETYPE(argv[offs]);
	evh_id     = STR2ETYPE(argv[offs+1]);

	maskset_config(id, mname, event_type, (lkst_evhandler_id)evh_id);
}

void call_read(int *argc, char **argv)
{
	int c;
	int rall = 0;
	int all = 0;
	int disp = 0;
	lkst_maskset_id id = LKST_MASKSET_ID_VOID;

	while((c = getopt(*argc, argv, "m:n:Aad")) != EOF) {
		switch(c) {
		case 'm' :
			id = STR2MID(optarg);
			break;
		case 'n' :
			strncpy(mname,optarg,LKST_MASKSET_NAME_LEN);
			break;
		case 'A' :
			rall = 1;
			break;
		case 'a' :
			all = 1;
			break;
		case 'd' :
			disp = 1;
			break;
		default :
			usage();
		}
	}

	if ( ( mname[0] && (id != LKST_MASKSET_ID_VOID)) ||
	     (( mname[0] || (id != LKST_MASKSET_ID_VOID)) && rall ) )
		needopt();

	if (rall) {
		maskset_read_all(all, disp);
	}else
		maskset_read(id, mname,  all, disp);

}

void call_set(int *argc, char **argv)
{
	int c;
	lkst_maskset_id id = LKST_MASKSET_ID_VOID;

	c = getopt(*argc, argv, "m:n:");

	switch(c) {
	case 'm' :
		id = STR2MID(optarg);
		break;
	case 'n' :
		strncpy(mname,optarg,LKST_MASKSET_NAME_LEN);
		break;
	case -1:
		needopt();
		break;
	default :
		usage();
		break;
	}

	if ( (!mname[0] && id == LKST_MASKSET_ID_VOID) || 
	     ( mname[0] && id != LKST_MASKSET_ID_VOID) )
		needopt();

	maskset_set(id,mname);
}


void call_write(int *argc, char **argv)
{
	int c;
	int set = 0;
	lkst_maskset_id id = LKST_MASKSET_ID_VOID;
	char file_name[255];

	strncpy(file_name, "-", 2); /* standard input */

	while((c = getopt(*argc, argv, "m:n:f:S")) != EOF) {
		switch(c) {
		case 'm' :
			id = STR2MID(optarg);
			break;
		case 'n' :
			strncpy(mname, optarg, 255);
			break;
		case 'f' :
			strncpy(file_name, optarg, 255);
			break;
		case 'S' :
			set = 1;
			break;
		default :
			usage();
		}
	}
	maskset_write(&id, file_name, mname);

	if (set)
		maskset_set(id,NULL);
}

void call_getid(int *argc, char **argv)
{
	int c;
	char name[LKST_MASKSET_NAME_LEN] = {"\0"};

	c = getopt(*argc, argv, "n:");

	switch(c) {
	case 'n' :
		strncpy(name, optarg, 255);
		break;
	case -1:
		needopt();
		break;
	default :
		usage();
		break;
	}

	if(name[0]=='\0')
		needopt();
	
	maskset_getid(name);
}
