/*
 * common.c
 *
 *  Created on: 2020�~5��27��
 *      Author: foluswen
 */

#include "Module_OcppBackend.h"

void refreshStartTimer(struct timespec *timer)
{
	clock_gettime(CLOCK_MONOTONIC, timer);
}

int getDiffSecNow(struct timespec timer)
{
	struct timespec timerNow;

	clock_gettime(CLOCK_MONOTONIC, &timerNow);

	return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
}

int getDiffSecBetween(struct timespec start, struct timespec end)
{
	return (int)((((unsigned long)(end.tv_sec - start.tv_sec) * 1000) + ((unsigned long)((end.tv_nsec / 1000000) - (start.tv_nsec / 1000000))))/1000);
}

void work(char s[])        // Delete space on start & end
{
	int i,j;

	for(i=0;s[i]==' ';i++);        		// Search first non space

	for(j=0;s[i];)s[j++]=s[i++];        // Delete space in start

	for(i--;s[i]==' ';i--)s[i]='\0';    // Delete space in end
}

char* strchr(const char *p, int ch)
{
    char c;

    c = ch;
    for (;; ++p) {
        if (*p == c)
            return ((char *)p);
        if (*p == '\0')
            return (NULL);
    }
    /* NOTREACHED */
    return NULL;
}

void splitstring(char *src, const char *separator, char **dest,int *num)
{
     char *pNext;
     int count = 0;
     if (src == NULL || strlen(src) == 0)
        return;

     if (separator == NULL || strlen(separator) == 0)
        return;

     pNext = (char *)strtok(src,separator);
     while(pNext != NULL)
     {
          *dest++ = pNext;
          ++count;
         pNext = (char *)strtok(NULL,separator);
    }
    *num = count;
}

char* stringtrim( char * s )
{
    char * p1 = s;
	char * p2 = s;
	while(*p1 != '\0')
	{
		while(*p1 == ' ' || *p1 == '\t' || *p1 == '\"' || *p1 == '\n' || *p1 == '}' || *p1 == '\r')
		{
			if(*p1 != ',')
			{
				p1 ++;
			}
			else
			{
				break;
			}

		}

		if(*p1 != ',')
		{
			* p2 ++ = *p1 ++;
			//printf("p2=%s\n",p2);
		}
		else
		{
			break;
		}

	}
	*p2 = '\0';
	return (s);
}

char* stringtrimspace( char * s )
{
    char * p1 = s;
	char * p2 = s;
	while(*p1 != '\0')
	{
		while(*p1 == ' ') //while(*p1 == ' ' || *p1 == '\t' || *p1 == '\n' || *p1 == '\r')
		{
			p1 ++;

		}

		* p2 ++ = *p1 ++;
		//printf("p2=%s\n",p2);
	}
	*p2 = '\0';
	return (s);
}

int DiffTimeb(struct timeb ST, struct timeb ET)
{
	//return milli-second
	unsigned int StartTime,StopTime;

	StartTime=(unsigned int)ST.time;
	StopTime=(unsigned int)ET.time;
	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
}

void trim(char *s)
{
    int i=0, j, k, l=0;

    while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
        i++;

    j = strlen(s)-1;
    while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
        j--;

    if(i==0 && j==strlen(s)-1) { }
    else if(i==0) s[j+1] = '\0';
    else {
        for(k=i; k<=j; k++) s[l++] = s[k];
        s[l] = '\0';
    }
}

int mystrcmp(char *p1,char *p2)
{
    while(*p1==*p2)
    {
        if(*p1=='\0' || *p2=='\0')
            break;
        p1++;
        p2++;
    }
    if(*p1=='\0' && *p2=='\0')
        return(PASS);
    else
        return(FAIL);
}

void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
{
	strncpy(dest, src + start, cnt);
	dest[cnt] = 0;
}

int strposs(char *source, char *substr, int idx)
{
   char stack[strlen(source)];
   int result=0;
   int count=0;

   while(count<=idx)
   {
	   memset(stack,0,sizeof stack);
	   strncpy(stack, source+result, strlen(source)-result);

	   int loc = strcspn(stack, substr);

	   if(loc>0)
		   result += (loc+1);
	   else
		   result = -1;

	   count++;
   }

   return result;
}

void getSubStr(char *dest, char* src, char *split, int idx)
{

	int start = (strposs(src,",",idx)+1);
	int cnt = (strposs(src,",",idx+1)-2)-(strposs(src,",",idx)+1);

	strncpy(dest, src + start, cnt);
	dest[cnt] = 0;
}

void split(char **arr, char *str, const char *del)
{
	char *s = strtok(str, del);

	while(s != NULL)
	{
		*arr++ = s;
		s = strtok(NULL, del);
	}
}

int strpos(char *source, char *substr, int skip)
{
   char stack[strlen(source)];
   strncpy(stack, source+skip, strlen(source)-skip);
   char *p = strstr(stack, substr);
   if (p)
      return p - stack+skip;
   return -1;
}

char* strtrim( char * s )
{
    char * p1 = s;
	char * p2 = s;
	while(*p1 != '\0')
	{
		while(*p1 == '\t' || *p1 == '\n' || *p1 == '\r') //while(*p1 == ' ' || *p1 == '\t' || *p1 == '\n' || *p1 == '\r')
		{
			p1 ++;

		}

		* p2 ++ = *p1 ++;
		//printf("p2=%s\n",p2);
	}
	*p2 = '\0';
	return (s);
}

char* strtrimc( char * s )
{
    char * p1 = s;
	char * p2 = s;
	while(*p1 != '\0')
	{
		while(*p1 == ' ' || *p1 == '\t' || *p1 == '\"' || *p1 == '\n' || *p1 == '}' || *p1 == '\r')
		{
			if(*p1 != ',')
			{
				p1 ++;
			}
			else
			{
				break;
			}
		}

		if(*p1 != ',')
		{
			* p2 ++ = *p1 ++;
			//printf("p2=%s\n",p2);
		}
		else
		{
			break;
		}
	}
	*p2 = '\0';
	return (s);
}

char* random_uuid(char* buf)
{
	uuid_t uuid;

	uuid_generate(uuid);
	uuid_unparse(uuid, buf);

	return 0;
}

//===========================================================
// URL parsing function
//===========================================================
/**
 * Parse a non null terminated string into an integer.
 *
 * str: the string containing the number.
 * len: Number of characters to parse.
 */
static inline int
natoi(const char *str, size_t len)
{
	int i, r = 0;
	for (i = 0; i < len; i++) {
		r *= 10;
		r += str[i] - '0';
	}

	return r;
}

/**
 * Check if a URL is relative (no scheme and hostname).
 *
 * url: the string containing the URL to check.
 *
 * Returns 1 if relative, otherwise 0.
 */
static inline int
is_relative(const char *url)
{
	return (*url == '/') ? 1 : 0;
}

/**
 * Parse the scheme of a URL by inserting a null terminator after the scheme.
 *
 * str: the string containing the URL to parse. Will be modified.
 *
 * Returns a pointer to the hostname on success, otherwise NULL.
 */
static inline char *
parse_scheme(char *str)
{
	char *s;

	/* If not found or first in string, return error */
	s = strchr(str, ':');
	if (s == NULL || s == str) {
		return NULL;
	}

	/* If not followed by two slashes, return error */
	if (s[1] == '\0' || s[1] != '/' || s[2] == '\0' || s[2] != '/') {
		return NULL;
	}

	*s = '\0'; // Replace ':' with NULL

	return s + 3;
}

/**
 * Find a character in a string, replace it with '\0' and return the next
 * character in the string.
 *
 * str: the string to search in.
 * find: the character to search for.
 *
 * Returns a pointer to the character after the one to search for. If not
 * found, NULL is returned.
 */
static inline char *
find_and_terminate(char *str, char find)
{
	str = strchr(str, find);
	if (NULL == str) {
		return NULL;
	}

	*str = '\0';
	return str + 1;
}

/* Yes, the following functions could be implemented as preprocessor macros
     instead of inline functions, but I think that this approach will be more
     clean in this case. */
static inline char *
find_fragment(char *str)
{
	return find_and_terminate(str, '#');
}

static inline char *
find_query(char *str)
{
	return find_and_terminate(str, '?');
}

static inline char *
find_path(char *str)
{
	return find_and_terminate(str, '/');
}

/**
 * Parse a URL string to a struct.
 *
 * url: pointer to the struct where to store the parsed URL parts.
 * u:   the string containing the URL to be parsed.
 *
 * Returns 0 on success, otherwise -1.
 */
int
yuarel_parse(struct yuarel *url, char *u)
{
	if (NULL == url || NULL == u) {
		return -1;
	}

	memset(url, 0, sizeof (struct yuarel));

	/* (Fragment) */
	url->fragment = find_fragment(u);

	/* (Query) */
	url->query = find_query(u);

	/* Relative URL? Parse scheme and hostname */
	if (!is_relative(u)) {
		/* Scheme */
		url->scheme = u;
		u = parse_scheme(u);
		if (u == NULL) {
			return -1;
		}

		/* Host */
		if ('\0' == *u) {
			return -1;
		}
		url->host = u;

		/* (Path) */
		url->path = find_path(u);

		/* (Credentials) */
		u = strchr(url->host, '@');
		if (NULL != u) {
			/* Missing credentials? */
			if (u == url->host) {
				return -1;
			}

			url->username = url->host;
			url->host = u + 1;
			*u = '\0';

			u = strchr(url->username, ':');
			if (NULL == u) {
				return -1;
			}

			url->password = u + 1;
			*u = '\0';
		}

		/* Missing hostname? */
		if ('\0' == *url->host) {
			return -1;
		}

		/* (Port) */
		u = strchr(url->host, ':');
		if (NULL != u && (NULL == url->path || u < url->path)) {
			*(u++) = '\0';
			if ('\0' == *u) {
				return -1;
			}

			if (url->path) {
				url->port = natoi(u, url->path - u - 1);
			} else {
				url->port = atoi(u);
			}
		}

		/* Missing hostname? */
		if ('\0' == *url->host) {
			return -1;
		}
	} else {
		/* (Path) */
		url->path = find_path(u);
	}

	return 0;
}

/**
 * Split a path into several strings.
 *
 * No data is copied, the slashed are used as null terminators and then
 * pointers to each path part will be stored in **parts. Double slashes will be
 * treated as one.
 *
 * path: the path to split.
 * parts: a pointer to an array of (char *) where to store the result.
 * max_parts: max number of parts to parse.
 */
int
yuarel_split_path(char *path, char **parts, int max_parts)
{
	int i = 0;

	if (NULL == path || '\0' == *path) {
		return -1;
	}

	do {
		/* Forward to after slashes */
		while (*path == '/') path++;

		if ('\0' == *path) {
			break;
		}

		parts[i++] = path;

		path = strchr(path, '/');
		if (NULL == path) {
			break;
		}

		*(path++) = '\0';
	} while (i < max_parts);

	return i;
}

int
yuarel_parse_query(char *query, char delimiter, struct yuarel_param *params, int max_params)
{
	int i = 0;

	if (NULL == query || '\0' == *query) {
		return -1;
	}

	params[i++].key = query;
	while (i < max_params && NULL != (query = strchr(query, delimiter))) {
		*query = '\0';
		params[i].key = ++query;
		params[i].val = NULL;

		/* Go back and split previous param */
		if (i > 0) {
			if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL) {
				*(params[i - 1].val)++ = '\0';
			}
		}
		i++;
	}

	/* Go back and split last param */
	if ((params[i - 1].val = strchr(params[i - 1].key, '=')) != NULL) {
		*(params[i - 1].val)++ = '\0';
	}

	return i;
}