#include <vector>
#include <iostream>
using namespace std;

void ParserCmd(char *p_sCmd, vector<string> &p_vCmdSet)
{
    string sCmd = p_sCmd;
    int p = sCmd.find(" "); 
    while (p != string::npos)
    {
        string sTemp = sCmd.substr(0, p);
        sCmd = sCmd.substr(p + 1, sCmd.length() - p - 1);
        p_vCmdSet.push_back((char*)sTemp.c_str());
        p = sCmd.find(" ");
    }
    p_vCmdSet.push_back((char*)sCmd.c_str());
}

bool MyCreateProcess(char *p_sAppName, char *p_sCmdArg, char *p_sEnvArg, int *p_nRetVal)
{
    if (!p_sAppName)
        return false;

    vector<string> vCmdSet;
    vCmdSet.clear();
    vCmdSet.push_back(p_sAppName);

    if (p_sCmdArg)
        ParserCmd(p_sCmdArg, vCmdSet);

    // Set environmnet pwd
    vector<string> vEnvArgSet;
    vEnvArgSet.clear();

    string sEnvPath;
    char *pEnvPath = NULL;

    sEnvPath = "LD_LIBRARY_PATH=";
    pEnvPath = getenv("LD_LIBRARY_PATH");
    char *pCurrentPath = getcwd(NULL, 0);
    if (pEnvPath)
        sEnvPath += (string(pEnvPath) + string(":") + string(pCurrentPath));
    else
        sEnvPath += string(pCurrentPath);
    free(pCurrentPath);
    vEnvArgSet.push_back((char*)sEnvPath.c_str());

    if (p_sEnvArg)
        ParserCmd(p_sEnvArg, vEnvArgSet);
    
    printf("-------------new--------------\n");
    char **ppCmdArg = new char*[vCmdSet.size() + 1];
    for (int i = 0; i < vCmdSet.size(); i++)
    {
        ppCmdArg[i] = NULL;
        ppCmdArg[i] = new char[vCmdSet[i].length() + 1];
        strcpy(ppCmdArg[i], vCmdSet[i].c_str());
        ppCmdArg[vCmdSet[i].length()] = 0;
        printf("ppCmdArg[%d] = %s\n", i, ppCmdArg[i]);
    }
    ppCmdArg[vCmdSet.size()] = NULL;
    printf("-------------new end--------------\n");

    printf("-------------test 1--------------\n");
    for (int i = 0; i < vCmdSet.size(); i++)
    {
        printf("ppCmdArg[%d] = %s\n", i, ppCmdArg[i]);
    }
    printf("-------------test 1 end--------------\n");   

    char **ppEnvArg = new char*[vEnvArgSet.size() + 1];
    for (int i = 0; i < vEnvArgSet.size(); i++)
    {
        ppEnvArg[i] = new char[vEnvArgSet[i].length() + 1];
        strcpy(ppEnvArg[i], vEnvArgSet[i].c_str());
        ppEnvArg[vEnvArgSet[i].length()] = 0;
    }
    ppEnvArg[vEnvArgSet.size()] = NULL;  

    printf("-------------test 2--------------\n");
    for (int i = 0; i < vCmdSet.size(); i++)
    {
        printf("ppCmdArg[%d] = %s\n", i, ppCmdArg[i]);
    }
    printf("-------------test 2 end--------------\n");   

    //-------------------------------------------------------
    bool bRet = false;
    pid_t pID = fork();  
    if (pID == -1)
    {
        printf("Error! CreateProcess %s fails, error = %d\n", p_sAppName, errno);
        return bRet;
    }
    else if (pID == 0)  // sub-process start here
    {

        if (execve(p_sAppName, ppCmdArg, ppEnvArg) < 0)
        {
            CUbiLogger::GetThis().Write("Error! Process %s fails, error = %d\n", p_sAppName, errno);
            _exit(-127);
        }
        else
        {
            bRet = true;
        }
    }
    else  // parent process wait here
    {
		int status;
		if (waitpid(pID, &status, 0) == -1)
		{
			prtinf("waitpid failed");
			return bRet;
		}

		if (WIFEXITED(status)) 
		{
			int nRet;
			nRet = WEXITSTATUS(status);
			if (p_nRetVal)
			{
				*p_nRetVal = nRet;
				if ((*p_nRetVal) == 0)
					bRet = true;
			}
			else
				bRet = true;
		}
	}
 #endif   
    //-------------------------------------------------------
    
    for (int i = 0; i < vCmdSet.size(); i++)
    {
        printf("ppCmdArg[%d] = %s\n", i, ppCmdArg[i]);
        if (ppEnvArg[i])
        {
            delete[] ppCmdArg[i];
            ppCmdArg[i] = NULL;
        }
    }
    delete[] ppCmdArg;

    printf("vEnvArgSet size = %d\n", vEnvArgSet.size());
    for (int i = 0; i < vEnvArgSet.size(); i++)
    {
        printf("ppEnvArg[%d] = %s\n", i, ppEnvArg[i]);
        if (ppEnvArg[i])
        {
            delete[] ppEnvArg[i];
            ppEnvArg[i] = NULL;
        }
    }    
    delete[] ppEnvArg;

    return bRet;
}