#include 	<sys/time.h>
#include 	<sys/timeb.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include 	<sys/types.h>
#include 	<sys/ioctl.h>
#include 	<sys/socket.h>
#include 	<sys/ipc.h>
#include 	<sys/shm.h>
#include 	<sys/shm.h>
#include 	<sys/mman.h>
#include 	<linux/can.h>
#include 	<linux/can/raw.h>
#include 	<linux/wireless.h>
#include 	<arpa/inet.h>
#include 	<netinet/in.h>

#include 	<unistd.h>
#include 	<stdarg.h>
#include    <stdio.h>      /*�зǿ�J��X�w�q*/
#include    <stdlib.h>     /*�зǨ�Ʈw�w�q*/
#include    <unistd.h>     /*Unix �зǨ�Ʃw�q*/
#include    <fcntl.h>      /*�ɱ���w�q*/
#include    <termios.h>    /*PPSIX �׺ݱ���w�q*/
#include    <errno.h>      /*���~���w�q*/
#include 	<errno.h>
#include 	<string.h>
#include	<time.h>
#include	<ctype.h>
#include 	<ifaddrs.h>
#include	"../../define.h"
#include 	"Config.h"

#define Debug
#define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
#define PASS				1
#define FAIL				-1
#define OUTPUT_FLASH		0x01
#define OUTPUT_FILE			0x02

struct SysConfigData 			SysConfig;

int StoreLogMsg(const char *fmt, ...);

int StoreLogMsg(const char *fmt, ...)
{
	char Buf[4096+256];
	char buffer[4096];
	va_list args;
	struct timeb  SeqEndTime;
	struct tm *tm;

	va_start(args, fmt);
	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
	va_end(args);

	memset(Buf,0,sizeof(Buf));
	ftime(&SeqEndTime);
	SeqEndTime.time = time(NULL);
	tm=localtime(&SeqEndTime.time);

	sprintf(Buf,"echo \"%04d-%02d-%02d %02d:%02d:%02d:%03d - %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog",
			tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,SeqEndTime.millitm,
			buffer,
			tm->tm_year+1900,tm->tm_mon+1);
	system(Buf);

	return rc;
}

void helpOutput(void)
{
	printf("Usage: Module_FactoryConfig [OPTION]...\r\n\r\n");
	printf("Generate factory default configuration value\r\n\r\n");
	printf("OPTION:\r\n");
	printf("	-a Write to file(/mnt) & flash\r\n");
	printf("	-f Write to file(/mnt)\r\n");
	printf("	-m Write to flash\r\n");
}

/**************************************************************************************/
/************This task will create Factory default confgiuration file *****************/
 /***********and store it into mtdblock 10,11,12                               ****************/
/**************************************************************************************/
int main(int argc,char *argv[])
{
	unsigned char outType=0;
	unsigned int i,Chk, MtdBlockSize=0x600000;
	unsigned char *ptr;
	int fd,wrd;

	ptr=malloc(MtdBlockSize);
	if(ptr==NULL)
	{
		#ifdef SystemLogMessage
		StoreLogMsg("[FactoryConfig]main: malloc for SysConfigData NG");
		#endif
		return 0;
	}
	memset(ptr, 0, MtdBlockSize);
	memset(&SysConfig, 0, sizeof(struct SysConfigData));

	/*
	 * TODO: Set factory default configuration
	*/
	//********** System **********// udhcpc -i eth1 -s ./dhcp_script/eth1.script
	//
	strcpy((char *)SysConfig.ModelName, "DSYE601J0EE2PH");
	strcpy((char *)SysConfig.SerialNumber, "NeedSetupSN");

	memset(SysConfig.SystemId, 0x00, sizeof(SysConfig.SystemId));

	strcat((char *)SysConfig.SystemId, (char *)SysConfig.ModelName);
	strcat((char *)SysConfig.SystemId, (char *)SysConfig.SerialNumber);

	strcpy((char *)SysConfig.SystemDateTime, "");
	SysConfig.AuthorisationMode = AUTH_MODE_ENABLE;
	SysConfig.DefaultLanguage = 0;
	SysConfig.RfidCardNumEndian = 0;
	SysConfig.AcPlugInTimes = 0;
	SysConfig.GbPlugInTimes = 0;
	SysConfig.Ccs1PlugInTime = 0;
	SysConfig.Ccs2PlugInTimes = 0;
	SysConfig.ChademoPlugInTimes = 0;
	SysConfig.BillingData.isBilling = 0;
	SysConfig.isAPP = 1;
	SysConfig.isQRCode = 1;
	SysConfig.isRFID = 1;
	//********** Charging **********//
	SysConfig.MaxChargingEnergy = 0;
	SysConfig.MaxChargingCurrent = 200;		// �̤j�i��X�q�y (���)
	SysConfig.MaxChargingDuration = 0;
	SysConfig.AcMaxChargingCurrent = 0;
	SysConfig.PhaseLossPolicy = 0;
	for(unsigned char i = 0; i < 10; i++)
		strcpy((char *)SysConfig.LocalWhiteCard, "");

	strcpy((char *)SysConfig.UserId, "");
	//********** Network **********//
	strcpy((char *)SysConfig.FtpServer, "");
	SysConfig.Eth0Interface.EthDhcpClient = 0;
	strcpy((char *) SysConfig.Eth0Interface.EthIpAddress, "192.168.1.10");
	strcpy((char *) SysConfig.Eth0Interface.EthSubmaskAddress, "255.255.255.0");
	strcpy((char *) SysConfig.Eth0Interface.EthGatewayAddress, "192.168.1.254");
	SysConfig.Eth1Interface.EthDhcpClient = 0;
	strcpy((char *) SysConfig.Eth1Interface.EthIpAddress, "192.168.0.10");
	strcpy((char *) SysConfig.Eth1Interface.EthSubmaskAddress, "255.255.255.0");
	strcpy((char *) SysConfig.Eth1Interface.EthGatewayAddress, "192.168.0.254");
	if(SysConfig.ModelName[10] == 'W')
		SysConfig.AthInterface.WifiMode = 2;
	else
		SysConfig.AthInterface.WifiMode = 0;
	strcpy((char *) SysConfig.AthInterface.WifiSsid, "");
	strcpy((char *) SysConfig.AthInterface.WifiPassword, "");
	SysConfig.AthInterface.WifiRssi = 0;
	SysConfig.AthInterface.WifiDhcpServer = 0;
	SysConfig.AthInterface.WifiDhcpClient = 0;
	strcpy((char *) SysConfig.AthInterface.WifiMacAddress, "");
	strcpy((char *) SysConfig.AthInterface.WifiIpAddress, "");
	strcpy((char *) SysConfig.AthInterface.WifiSubmaskAddress, "");
	strcpy((char *) SysConfig.AthInterface.WifiGatewayAddress, "");
	SysConfig.AthInterface.WifiNetworkConn = 0;
	strcpy((char *) SysConfig.TelecomInterface.TelcomModelName, "");
	strcpy((char *) SysConfig.TelecomInterface.TelcomSoftwareVer, "");
	//strcpy((char *) SysConfig.TelecomInterface.TelcomApn, "Internet");
	strcpy((char *) SysConfig.TelecomInterface.TelcomApn, "");
	SysConfig.TelecomInterface.TelcomRssi = 0;
	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapId, " ");
	strcpy((char *) SysConfig.TelecomInterface.TelcomChapPapPwd, " ");
	strcpy((char *) SysConfig.TelecomInterface.TelcomModemImei, "");
	strcpy((char *) SysConfig.TelecomInterface.TelcomSimImsi, "");
	strcpy((char *) SysConfig.TelecomInterface.TelcomSimIccid, "");
	SysConfig.TelecomInterface.TelcomSimStatus = 0;
	SysConfig.TelecomInterface.TelcomModemMode = 0;
	strcpy((char *) SysConfig.TelecomInterface.TelcomIpAddress, "");
	SysConfig.TelecomInterface.TelcomNetworkConn = 0;
	strcpy((char *)SysConfig.chargePointVendor, "Phihong Technology");
	//********** Backend **********//
	SysConfig.BackendConnTimeout = 300; //300 seconds
	SysConfig.OfflinePolicy = 2;
	SysConfig.OfflineMaxChargeEnergy = 0;
	SysConfig.OfflineMaxChargeDuration = 0;
	strcpy((char *) SysConfig.OcppServerURL, "");
	strcpy((char *) SysConfig.ChargeBoxId, "");
	SysConfig.LedInfo.Intensity = 2;

	//copy default configuration to pointer
	memcpy(ptr,&SysConfig,sizeof(struct SysConfigData));

	//calculate CRC
	Chk=0;
	for(i=0;i<(MtdBlockSize-4);i++)
	{
		Chk+=*(ptr+i);
	}
	memcpy(	ptr+MtdBlockSize-4,&Chk,4);

	/*
	* Parameter process
	*/
	if (argc > 1)
	{
		char *arg = argv[1];
		switch (arg[0])
		{
		case '-':
			switch (arg[1])
			{
				case 'a':
					outType |= OUTPUT_FILE;
					outType |= OUTPUT_FLASH;
					break;
				case 'f':
					outType |= OUTPUT_FILE;
					break;
				case 'm':
					outType |= OUTPUT_FLASH;
					break;
				default:
					helpOutput();
					break;
			}
				break;
			default:
				helpOutput();
				break;
		}
	}
	else
	{
		helpOutput();
	}

	/*
	 * Configuration bin file generate
	*/
	if((outType&OUTPUT_FILE)>0)
	{
		fd = open("/mnt/FactoryDefaultConfig.bin", O_RDWR | O_CREAT);
		if (fd < 0)
		{
			StoreLogMsg("[FactoryConfig]main: open /mnt/FactoryDefaultConfig.bin NG");
			free(ptr);
			return 0;
		}
		wrd=write(fd, ptr, MtdBlockSize);
		close(fd);
		if(wrd<MtdBlockSize)
		{
			StoreLogMsg("write /mnt/FactoryDefaultConfig.bin NG\r\n");
			free(ptr);
			return 0;
		}
		StoreLogMsg("FactoryConfig write to file in /mnt OK.\r\n");
	}

	/*
	* Flash memory write
	*/
	if((outType&OUTPUT_FLASH)>0)
	{
		// Save factory default setting value to flash factory default setting block
		fd = open("/dev/mtdblock12", O_RDWR);
		if (fd < 0)
		{
			StoreLogMsg("open /dev/mtdblock12 NG\r\n");
			free(ptr);
			return 0;
		}
		wrd=write(fd, ptr, MtdBlockSize);
		close(fd);
		if(wrd<MtdBlockSize)
		{
			StoreLogMsg("write /dev/mtdblock12 NG\r\n");
			free(ptr);
			return 0;
		}

		// Save factory default setting value to flash backup setting block
		fd = open("/dev/mtdblock11", O_RDWR);
		if (fd < 0)
		{
			StoreLogMsg("open /dev/mtdblock11 NG\r\n");
			free(ptr);
			return 0;
		}
		wrd=write(fd, ptr, MtdBlockSize);
		close(fd);
		if(wrd<MtdBlockSize)
		{
			StoreLogMsg("write /dev/mtdblock11 NG\r\n");
			free(ptr);
			return 0;
		}

		// Save factory default setting value to flash setting block
		fd = open("/dev/mtdblock10", O_RDWR);
		if (fd < 0)
		{
			StoreLogMsg("open /dev/mtdblock10 NG\r\n");
			free(ptr);
			return 0;
		}
		wrd=write(fd, ptr, MtdBlockSize);
		close(fd);
		if(wrd<MtdBlockSize)
		{
			StoreLogMsg("write /dev/mtdblock10 NG\r\n");
			free(ptr);
			return 0;
		}
		StoreLogMsg("FactoryConfig write to flash OK\r\n");
	}

	free(ptr);

	return FAIL;
}