
#include "shell.h"
#include "cpuid.h"

//-------------------------------------------------------------------------

ShellCmdItem g_cmdList[MAX_CMD_NUM];
int g_cmdNum = 0;

//-------------------------------------------------------------------------

void ChangeToUper(char * str)
{
	char tmp;
	while (str != NULL)
	{
		tmp = *str;
		if (tmp == 0)
		{
			break;
		}

		if (tmp >= 'a' && tmp <= 'z')
		{
			tmp -= ('a'-'A');
			*str = tmp;
		}
		str++;
	}
}

int AddShellCmd(const char*pCmd, const char*pHelp, ShellFunc func)
{
	if (g_cmdNum < MAX_CMD_NUM)
	{
		if ((strlen(pCmd) >= MAX_CMD_STR))
		{
			memcpy(g_cmdList[g_cmdNum].cmdstr, pCmd, MAX_CMD_STR-1);
			g_cmdList[g_cmdNum].cmdstr[MAX_CMD_STR-1] = 0;
		}
		else
		{
			strcpy(g_cmdList[g_cmdNum].cmdstr, pCmd);
		}

		ChangeToUper(g_cmdList[g_cmdNum].cmdstr);
#if (1)		// 改为指针
		g_cmdList[g_cmdNum].helpstr = pHelp;
#else
		if ((strlen(pHelp) >= MAX_HELP_STR))
		{
			memcpy(g_cmdList[g_cmdNum].helpstr, pHelp, MAX_HELP_STR-1);
			g_cmdList[g_cmdNum].helpstr[MAX_HELP_STR-1] = 0;
		}
		else
		{
			strcpy(g_cmdList[g_cmdNum].helpstr, pHelp);
		}
#endif
		g_cmdList[g_cmdNum].shellfunc = func;
		g_cmdNum++;
		return g_cmdNum;
	}
	else
	{
		printf("AddShellCmd failed, g_cmdNum=%d\r\n", g_cmdNum);
		return -1;
	}
}

int ShellTask(void)
{
	int i, j, k;
	int sta;
	char ch, ch1;
	char command[MAX_CMD_LINE];
	char cmd[MAX_CMD_LINE];
	char para1[MAX_CMD_LINE];
	char para2[MAX_CMD_LINE];
	int cmdlen, para1len, para2len;
	int cmdstrlen;

	if (IsNewCommand() == 0)	// 检测命令
	{
		return -1;
	}

	// 解析得到命令和参数
	cmdstrlen = LockExecAndGetCmdStr(command);

	sta = 0;
	cmdlen = 0;
	para1len = 0;
	para2len = 0;

	cmd[0] = 0;
	para1[0] = 0;
	para2[0] = 0;

	for(i = 0; i < cmdstrlen; i++)
	{
		ch = command[i];
//		printf("0x%x ", ch);
		if (sta == 0)
		{
			if (cmdlen == 0 && ch == ' ')	// 前空格
			{
				continue;
			}
			else if (cmdlen != 0 && ch == ' ')	// 后空格
			{
				cmd[cmdlen] = 0;
				sta = 1;
			}
			else
			{
				if (cmdlen < MAX_CMD_LINE-1)
				{
					cmd[cmdlen] = ch;
					cmdlen++;
				}
			}
		}
		else if (sta == 1)
		{
			if (para1len == 0 && ch == ' ')			// 前空格
			{
				continue;
			}
			else if (para1len != 0 && ch == ' ')	// 后空格
			{
				para1[para1len] = 0;
				sta = 2;
			}
			else
			{
				if (para1len < MAX_CMD_LINE-1)
				{
					para1[para1len] = ch;
					para1len++;
				}
			}
		}
		else if (sta == 2)
		{
			if (para2len == 0 && ch == ' ')			// 前空格
			{
				continue;
			}
			else if (para2len != 0 && ch == ' ')	// 后空格
			{
				para2[para2len] = 0;
				sta = 3;
			}
			else
			{
				if (para2len < MAX_CMD_LINE-1)
				{
					para2[para2len] = ch;
					para2len++;
				}
			}
		}
		else
		{
			break;
		}
	}

	cmd[cmdlen] = 0;
	para1[para1len] = 0;
	para2[para2len] = 0;

//	printf("cmd=%s,para1=%s,para2=%s", cmd, para1, para2);

	ChangeToUper(cmd);
	ChangeToUper(para1);
	ChangeToUper(para2);

	// 执行命令
	for (i = 0; i < g_cmdNum; i++)
	{
		if (strcmp(g_cmdList[i].cmdstr, cmd) == 0)
		{
			if (g_cmdList[i].shellfunc != NULL)
			{
				g_cmdList[i].shellfunc(para1, para2);
			}
			break;
		}
	}

	if (i >= g_cmdNum)	// 没有找到匹配命令，寻找局部匹配命令
	{
		k = -1;
		for (i = 0; i < g_cmdNum; i++)
		{
			for (j = 0; j < cmdlen; j++)
			{
				ch = cmd[j];
				ch1 = g_cmdList[i].cmdstr[j];
				if (ch == ' ' || ch == 0 || ch1 == ' ' || ch1 == 0)	// 命令结束
				{
					break;
				}

				if (ch != ch1)
				{
					break;
				}
			}

			if (j == cmdlen && cmdlen != 0)	// 匹配输入命令
			{
				k = i;
				break;
			}
		}

		if (k >= 0)	// 有匹配的
		{
			if (g_cmdList[k].shellfunc != NULL)
			{
				g_cmdList[k].shellfunc(para1, para2);
			}
		}
	}

	OutNewCmdLine();
	UnlockExec();

	return 0;
}

//-------------------------------------------------------------------------

// 版本命令
void VersionInfo(char * para1, char * para2)
{
	char buff[VERSION_LEN+1];

	GetVersionStr(buff);
	buff[VERSION_LEN] = 0;
	printf("Software Version = %s\r\n", buff);
	GetBuildStr(buff);
	printf("%s\r\n", buff);
}

// 帮助命令
void HelpString(char * para1, char * para2)
{
	int i;
	if (para1 == para2)
	{
	}

	for (i = 0; i < g_cmdNum; i++)
	{
		printf("\r\n%s\r\n", g_cmdList[i].cmdstr);
		printf("\t%s\r\n", g_cmdList[i].helpstr);
	}
}

// 清屏命令
void CleanScreen(char * para1, char * para2)
{
	if (para1 == para2)
	{
	}
	putchar(0x0C);	// 清屏
}

void Restart(char * para1, char * para2)
{
	RestartMcu();
}

void ShowHistoryCmd(char * para1, char * para2)
{
	if (para1 == NULL || para2 == NULL)
	{
		return;
	}

	int num = GetHistoryNum();		// 已经存储的历史命令个数
	int maxnum = GetHistoryMaxNum();
	int rslt;
	char ch[MAX_CMD_LINE];

	printf("show all history cmd:\r\n");

	if (num == maxnum)
	{
		int i = 0;
		for (int idx = GetHistoryIdx(); idx < maxnum; idx++)
		{
			rslt = GetHistoryCmd(idx, &ch[0]);
			if (rslt == 0)
			{
				printf("\t%d.%s\r\n", i+1, ch);
				i++;
			}
		}
		for (int idx = 0; idx < GetHistoryIdx(); idx++)
		{
			rslt = GetHistoryCmd(idx, &ch[0]);
			if (rslt == 0)
			{
				printf("\t%d.%s\r\n", i+1, ch);
				i++;
			}
		}
	}
	else if (num < maxnum)
	{
		for (int i = 0; i < num; i++)
		{
			rslt = GetHistoryCmd(i, &ch[0]);
			if (rslt == 0)
			{
				printf("\t%d.%s\r\n", i+1, ch);
			}
		}
	}
}

//-------------------------------------------------------------------------


void InitShell(void)
{
	InitConsole();		// 初始化控制台

	memset(g_cmdList, 0, sizeof(ShellCmdItem)*MAX_CMD_NUM);
	g_cmdNum = 0;

	// 基本命令
	AddShellCmd("HELP", "show the help info", HelpString);
	AddShellCmd("VERSION", "show the version info", VersionInfo);
//	AddShellCmd("CLS", "clean the screen", CleanScreen);
	AddShellCmd("REBOOT", "reboot the mcu", Restart);

//	AddShellCmd("HISTORY", "show all history cmd", ShowHistoryCmd);

}
