/************************************************************
 *
 * 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>
 *
 ************************************************************/

#include "command.h"
#include "buffer.h"
#include "maskset.h"
#include "evhandler.h"


#define NAME	"lkst"
#define VERSION "1.2"

#define NR_CMD 8

void usage(void);
void lkst_status(void);
void lkst_start(void);
void lkst_stop(void);

void call_usage(int*, char**);
void call_version(int*, char**);
void call_all(int*, char**);
void call_status(int*, char**);
void call_start(int*, char**);
void call_stop(int*, char**);

int main(int argc, char **argv)
{

	int i;

	struct command cmd[] = 
	{
		[0] = {"help", &call_usage},
		[1] = {"ver", &call_version},
		[2] = {"version", &call_version},
		[3] = {"all", &call_all},
		[4] = {"status", &call_status},
		[5] = {"stat", &call_status},
		[6] = {"start", &call_start},
		[7] = {"stop", &call_stop},
	};

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

	exit(0);
}

void usage(void)
{
	printf("This controls status of LKST.\n");
	printf("Usage:\n\t%s [command]\n\n", NAME);
	printf("<COMMAND>\n");
	printf("all\t\tOutput a current status and list of buffers, masksets,\n");
	printf("\t\tand event handlers.\n");
	printf("status/stat\tOutput a current status.\n");
	printf("start\t\tStart event tracing.\n");
	printf("stop\t\tStop event tracing.\n");
	printf("version/ver\tPrint version of this command.\n");
	printf("help\t\tPrint this message.\n\n");
	printf("<SEE ALSO>\n");
	printf("lkstm\t\tControls Masksets.\n");
	printf("lkstbuf\t\tControls kernel event buffers.\n");
	printf("lksteh\t\tControls event handlers.\n");
	printf("lkstlogger\tTells event occurring to LKST.\n");
	printf("lkstlogd\tInvokes a log-outputting daemon.\n");
	exit(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)
{
	printf("<Current status>\n");
	lkst_status();

	printf("<List of buffers>\n");
	classical_buffer_list(-1);

	printf("<List of masksets>\n");
	maskset_list();

	printf("<List of event handlers>\n");
	evhandler_list();
}

void call_status(int *argc, char **argv)
{
	printf("<Current status>\n");
	lkst_status();
}

void call_start(int *argc, char **argv)
{
	lkst_start();
}

void call_stop(int *argc, char **argv)
{
	lkst_stop();
}

void lkst_status(void)
{
	int retval;
	int fd;
	int i,cpu;
	struct lkst_status_param param;

	fd = open_dev();

	retval = ioctl(fd, LKST_IOC_TRC_STATUS, &param); /* trc_status */

	if (retval<0) {
		fprintf(stderr, "ioctl(LKST_IOC_TRC_STATUS) error: %s\n", strerror(errno));
		exit(1);
	}

	cpu=0;
	for(i = 0; i < LKST_CPU_MAX; i++)
		if (param.online_cpu & (1UL<<i)) cpu++;
	printf("version of LKST         : %d.%d.%d\n", param.version.major,
	       param.version.minor, param.version.revision);
	printf("number of cpus          : %d\n", cpu);
	printf("number of masksets      : %d\n", param.maskset_num);
	printf("number of event-handlers: %d\n", param.evhandler_num);
	printf("current maskset_id      : %d\n", param.current_maskset_id);
	for(i = 0; i < LKST_CPU_MAX; i++)
		if (param.online_cpu & (1UL<<i))
			printf("current writing buffer_id (cpu: %03d): %d \n",
			       i, param.write_buffer_id[i]);

	close(fd);
}

void lkst_start(void)
{
	int retval;
	int fd;

	fd = open_dev();

	retval = ioctl(fd, LKST_IOC_TRC_START); /* trc_start */

	if (retval<0) {
		fprintf(stderr, "ioctl(LKST_IOC_TRC_START) error: %s\n", strerror(errno));
		exit(1);
	}

	printf("Start LKST event tracing.\n");

	close(fd);
}

void lkst_stop(void)
{
	int retval;
	int fd;

	fd = open_dev();

	retval = ioctl(fd, LKST_IOC_TRC_STOP); /* trc_stop */

	if (retval<0) {
		fprintf(stderr, "ioctl(LKST_IOC_TRC_STOP) error: %s\n", strerror(errno));
		exit(1);
	}

	printf("Stop LKST event tracing.\n");

	close(fd);
}
