/*
 * oclh_h_internals.c
 *      Author: havock
 */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <oclh_h_internals.h>
#include <oclh_h_errors.h>

uint64_t __ghf_removePreNPostSpacesFromCharPtr(char* const pcStr) {
    if(!pcStr || !pcStr[0]) return(0ul);
    uint64_t u64NofRemovedSpaces=0ul;
    { /* preSpaces remove */
        uint64_t i=0ul;
        while(pcStr[i] && isspace(pcStr[i])) i++;
        if(i && pcStr[i]!='\0') {
            uint64_t j=i, k=0ul;
            while(pcStr[j]) pcStr[k++]=pcStr[j++];
            pcStr[k]='\0';
            u64NofRemovedSpaces+=i;
        }
    }
    { /*postSpaces remove */
        uint64_t i=0ul;
        while(pcStr[i]) i++;
        i--;
        while(isspace(pcStr[i]) && i) {
            pcStr[i]='\0'; i--; u64NofRemovedSpaces++;
        }
        if(!i && isspace(pcStr[i])) { pcStr[i]='\0'; u64NofRemovedSpaces++; }
    }
    return(u64NofRemovedSpaces);
}

uint64_t __ghf_replaceIllegalFSCharsInCharPtr(char* const pcStr) {
    if(pcStr) {
/* TODO: optimize and clean */
        uint64_t u64NofReplaced=0ul, i=0ul;
        char cPrev='\0';
        int32_t i32IncFlag=1;
        while(pcStr[i]) {
            if(pcStr[i]=='(') {
                if(!strncmp(&pcStr[i],"(R)",3) || !strncmp(&pcStr[i],"(r)",3) ||
                   !strncmp(&pcStr[i],"(C)",3) || !strncmp(&pcStr[i],"(c)",3)) {
                    uint64_t j=i, k=i+3ul;
                    while(pcStr[k]) { pcStr[j]=pcStr[k]; k++; j++; }
                    pcStr[j]='\0';
                }
                if(!strncmp(&pcStr[i],"(TM)",4)||!strncmp(&pcStr[i],"(Tm)",4)||
                   !strncmp(&pcStr[i],"(tM)",4)||!strncmp(&pcStr[i],"(tm)",4)) {
                    uint64_t j=i, k=i+4ul;
                    while(pcStr[k]) { pcStr[j]=pcStr[k]; k++; j++; }
                    pcStr[j]='\0';
                }
            }
            if(pcStr[i]=='/' || pcStr[i]=='\\' || pcStr[i]=='?' ||
               pcStr[i]=='%' || pcStr[i]=='*'  || pcStr[i]==':' ||
               pcStr[i]=='|' || pcStr[i]=='"'  || pcStr[i]=='<' ||
               pcStr[i]=='>' || pcStr[i]==','  || pcStr[i]==';' ||
               pcStr[i]=='=' || pcStr[i]=='&'  || pcStr[i]=='#' ||
               pcStr[i]=='$' || pcStr[i]=='@'  || pcStr[i]=='(' ||
               pcStr[i]==')') { pcStr[i]=' '; u64NofReplaced++; }
            if(isspace(pcStr[i]) && isspace(cPrev)) {
                uint64_t j=i, k=i+1ul;
                while(pcStr[k]) { pcStr[j]=pcStr[k]; k++; j++; }
                pcStr[j]='\0';
                i32IncFlag=0;
            };
            if(i32IncFlag) { cPrev=pcStr[i]; i++; } else i32IncFlag=1;
        }
        return(u64NofReplaced);
    } else return(0ul);
}
uint64_t __ghf_replaceSpacesWithUnderscoreInCharPtr(char* const pcStr) {
    if(pcStr) {
        uint64_t u64NofReplacedSpaces=0ul, i=0ul;
        while(pcStr[i]) {
            if(isspace(pcStr[i])) { pcStr[i]='_'; u64NofReplacedSpaces++; }
            i++;
        }
        return(u64NofReplacedSpaces);
    } else return(0ul);
}

int32_t  __ghf_concatHeapStrAndCharPtr(char** ppcDst, const char* const pcStr) {
    if(ppcDst) {
        char* pcTmp=NULL;
        pcTmp=realloc(*ppcDst,
                    (*ppcDst?strlen(*ppcDst):0ul)+
                    (pcStr?strlen(pcStr):0ul)+2ul);
        if(!pcTmp) return(_GHM_HOST_MEMALLOC_ERROR);
        *ppcDst=pcTmp;
        strncat(*ppcDst," ",1ul); strncat(*ppcDst,pcStr,strlen(pcStr));
        return(_GHM_OK);
    } else return(_GHM_NULL_POINTER_RECEIVED_ERROR);
}

int32_t __ghf_cmpCharPtrAndWC(const char*           pcStr,
                              const char*           pcPattern,
                              const __GHE_CASE_SENS CaseSensFlag) {
    const char* pcPatternPos=NULL;
    const char* pcStrPos=NULL;
    while(*pcStr) {
        if((*pcPattern)=='*') {
            pcPatternPos=(++pcPattern);
            pcStrPos=pcStr;
            if(!*pcPattern) return(1);
            continue;
        }
        if( ((CaseSensFlag==__GHE_CASE_SENSITIVE)?
                (*pcStr!=(*pcPattern)):(tolower(*pcStr)!=tolower(*pcPattern)))
            && (*pcPattern)!='?') {
            if(!pcPatternPos) return(0);
            pcStr=(++pcStrPos);
            pcPattern=pcPatternPos;
            continue;
        }
        pcPattern++, pcStr++;
    }
    while((*pcPattern)=='*') pcPattern++;
    return((*pcPattern)=='\0');
}
