/*  Copyright (C) MOXA Inc. All rights reserved.

	This software is distributed under the terms of the
	MOXA License.  See the file COPYING-MOXA for details.
*/
#include <iostream>
#include "mx-uart-ctl.h"
#include<getopt.h>  
#pragma comment(lib,"getopt.lib") 

#define UNSET -1

enum action_type {
	GET_MODE = 0,
	SET_MODE = 1
};

struct action_struct {
	int type;
	int port;
	int mode;
};

void usage(FILE *fp)
{
	fprintf(fp, "Usage:\n");
	fprintf(fp, "	mx-uart-ctl -p <#port_number> -m <#uart_mode>\n\n");
	fprintf(fp, "OPTIONS:\n");
	fprintf(fp, "	-p <#port_number>\n");
	fprintf(fp, "		Set target port: [0..]\n");
	fprintf(fp, "	-m <#uart_mode>\n");
	fprintf(fp, "		Set target port to uart_mode\n");
	fprintf(fp, "		0 --> set to RS232 mode\n");
	fprintf(fp, "		1 --> set to RS485-2W mode\n");
	fprintf(fp, "		2 --> set to RS422 / RS485-4W mode\n");
	fprintf(fp, "\n");
	fprintf(fp, "Example:\n");
	fprintf(fp, "	Get mode from port 0\n");
	fprintf(fp, "	# mx-uart-ctl -p 0\n");
	fprintf(fp, "\n");
	fprintf(fp, "	Set port 1 to mode RS232\n");
	fprintf(fp, "	# mx-uart-ctl -p 1 -m 0\n");
}

int my_atoi(const char *nptr, int *number)
{
	int tmp;

	tmp = atoi(nptr);
	if (tmp != 0) {
		*number = tmp;
		return 0;
	}
	else {
		if (!strcmp(nptr, "0")) {
			*number = 0;
			return 0;
		}
	}
	return -1;
}

void show_uart_mode_message(int mode)
{
	switch (mode) {
	case UART_MODE_RS232:
		printf("Current uart mode is RS232 interface.\n");
		break;
	case UART_MODE_RS485_2W:
		printf("Current uart mode is RS485-2W interface.\n");
		break;
	case UART_MODE_RS422_RS485_4W:
		printf("Current uart mode is RS422/RS485-4W interface.\n");
		break;
	case NOTSUPPORT:
		printf("Not Support.\n");
		break;
	default:
		printf("Unknown interface is set.\n");
		break;
	}
}

void do_action(struct action_struct action)
{
	int ret;

	switch (action.type) {
	case GET_MODE:
		ret = GetUartMode(action.port);
		if (ret == -1) {
			printf("Unknown interface is set.\n");
			exit(1);
		}
		else if (ret == -2)
		{
			printf("Search device fail, please check device status.\n");
			exit(1);
		}
		break;
	case SET_MODE:
		ret = SetUartMode(action.port, action.mode);

		if (ret == -1) {
			printf("Unknown interface is set.\n");
			exit(1);
		}
		else if (ret == -2)
		{
			printf("Search device fail, please check device status.\n");
			exit(1);
		}
		
		if (ret != 0)
		{
			printf("Error code = %d.\n", ret);
			exit(1);
		}
		else
		{
			printf("Set OK.\n");
		}
		
		ret = GetUartMode(action.port);
		if (ret < 0) {
			printf("Unknown interface is set.\n");
			exit(1);
		}
		break;
	}

	show_uart_mode_message(ret);
}

int main(int argc, char *argv[])
{
	struct action_struct action = {	GET_MODE,	UNSET,	UNSET};
	int c;

	while (1) {
		c = getopt(argc, argv, "hp:m:");
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			usage(stdout);
			exit(0);
		case 'p':
			if (my_atoi(optarg, &action.port) != 0) {
				fprintf(stderr, "%s is not a number\n", optarg);
				exit(1);
			}
			break;
		case 'm':
			action.type = SET_MODE;
			if (my_atoi(optarg, &action.mode) != 0) {
				fprintf(stderr, "%s is not a number\n", optarg);
				exit(1);
			}
			break;
		default:
			usage(stderr);
			exit(99);
		}
	}

	if (optind < argc) {
		fprintf(stderr, "non-option arguments found: ");
		while (optind < argc)
			fprintf(stderr, "%s ", argv[optind++]);
		fprintf(stderr, "\n");

		usage(stderr);
		exit(99);
	}

	if (action.port == UNSET) {
		fprintf(stderr, "port number is unset\n");
		usage(stderr);
		exit(99);
	}

	do_action(action);

	exit(0);
}

