/*
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 <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>  
#pragma comment(lib,"getopt.lib") 
#include "mx5Gpower.h"
using namespace std;

#define UNSET 	-1

enum action_type {
	GET_POWER_STATUS = 0,
	SET_POWER_STATUS = 1,
	SET_MODULE_RESET = 2
};

struct action_struct {
	int type;
	int status;
	int socket;
};

void usage(FILE *fp)
{
	fprintf(fp, "Usage:\n");
	fprintf(fp, "	mx-5Gpower-ctl -s <M.2B socket index> [-p <Power status>][-r]\n");
	fprintf(fp, "OPTIONS:\n");
	fprintf(fp, "	-s <#M.2B socket index>\n");
	fprintf(fp, "		Target module socket index: [1..]\n");
	fprintf(fp, "		Get module power status\n");
	fprintf(fp, "	-p <#Power status>\n");
	fprintf(fp, "		Set 5G module power status\n");
	fprintf(fp, "		1 --> power on\n");
	fprintf(fp, "		0 --> power off\n");
	fprintf(fp, "	-r <>\n");
	fprintf(fp, "		Set 5G module hardware reset\n");
	fprintf(fp, "	-h <>\n");
	fprintf(fp, "		Print this message and exits\n");
	fprintf(fp, "\n");
	fprintf(fp, "Example:\n");
	fprintf(fp, "	Get M.2B socket 1 5G module power status\n");
	fprintf(fp, "	    # mx-5Gpower-ctl -s 1\n");
	fprintf(fp, "	Set M.2B socket 1 5G module power on\n");
	fprintf(fp, "	    # mx-5Gpower-ctl -s 1 -p 1\n");
	fprintf(fp, "   Reset socket 1 5G module\n");
	fprintf(fp, "	    # mx-5Gpower-ctl -s 1 -r\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 do_action(struct action_struct action)
{
	switch (action.type) {
	case GET_POWER_STATUS:
		action.status = GetPowerStatus(action.socket - 1);
		if (action.status < 0) {
			fprintf(stderr, "Failed to get 5G module status\n");
			exit(1);
		}
		else if(action.status == 1)
			printf("5G module status: ON\n");
		else if (action.status == 0)
			printf("5G module status: OFF\n");
		break;
	case SET_POWER_STATUS:
		if (SetPowerStatus(action.socket - 1, action.status) < 0) {
			fprintf(stderr, "Failed to set 5G module status\n");
			exit(1);
		}
		else
		{
			if (action.status)
				printf("Set 5G module power on.\n");
			else
				printf("Set 5G module power off.\n");
		}
		break;
	case SET_MODULE_RESET:
		if (ResetModule(action.socket - 1) < 0) {
			fprintf(stderr, "Failed to reset 5G module\n");
			exit(1);
		}
		else
		{
			printf("5G module reset.\n");
		}
		break;
	}
}

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

	while (1) {
		c = getopt(argc, argv, "hs:p:r");
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			usage(stdout);
			exit(0);
		case 's':
			if (my_atoi(optarg, &action.socket) != 0) {
				fprintf(stderr, "%s is not a number\n", optarg);
				exit(1);
			}
			break;
		case 'p':
			action.type = SET_POWER_STATUS;
			if (my_atoi(optarg, &action.status) != 0) {
				fprintf(stderr, "%s is not a number\n", optarg);
				exit(1);
			}
			break;
		case 'r':
			action.type = SET_MODULE_RESET;
			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);
	}

	do_action(action);
	exit(0);
}