#include "utility.h"
#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 
#include <iostream>
#include <iconv.h>
#include <string.h>
#include <sys/time.h>
#include <chrono>

#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

//函数名: GetProcDir() 
//功  能: 获取当前程序的路径 
std::string GetProcDir()
{
    std::string strDir;
#ifdef WIN32
#else    
    char szBuffer[256]; 
    int npos = 0; 
    npos = readlink( "/proc/self/exe", szBuffer, 256 ); 
    if ( npos < 0 || npos >= 256 ) 
    { 
        printf( "readlink failed.\n" ); 
        return strDir; 
    } 
    szBuffer[npos] = '\0'; 
    char *ptr = NULL;  
    char c = '/';      
    ptr = strrchr(szBuffer,c);  
    if(ptr != NULL)
        *(ptr +1) = 0;
    strDir = szBuffer;
#endif
    return strDir;
}

int charset_convert(const char* charset_from, const char* charset_to, const std::string& string_from, std::string& string_to)
{
    iconv_t cd = iconv_open(charset_to, charset_from);
    if (!cd)
    {
        return -1;
    }

    string_to = "";
    int ret = 0;
    size_t inbytes = string_from.size();
    char* inbuf = const_cast<char*>(string_from.c_str());
    while (inbytes > 0)
    {
        char buffer[2048] = {0};
        char *outbuf = buffer;
        size_t outbytes = sizeof(buffer) - 1;
        ret = iconv(cd, &inbuf, &inbytes, &outbuf, &outbytes);
        if (ret == 0 || errno == E2BIG)
        {
            string_to.append(buffer);
        }
        else
        {
            break;
        }
    }
    ret = iconv_close(cd);
    if (inbytes != 0 || ret != 0)
    {
        return -1;
    }

    return 0;
}

//GB2312码转为UNICODE码
std::string charset_g2u(const std::string& gb2312)
{
    std::string utf8;
    charset_convert("gb2312", "utf-8", gb2312, utf8);
    //std::cout<<"convert res:"<<i<<std::endl;
    return utf8;
}

//UNICODE码转为GB2312码
std::string charset_u2g(const std::string& utf8)
{
    std::string gb2312;
    charset_convert( "utf-8","gb2312", utf8, gb2312);
    //std::cout<<"convert res:"<<i<<std::endl;
    return gb2312;
}

//获取时间戳（毫秒）
int64_t timestamps_milliseconds()
{
   struct timeval tv;    
   gettimeofday(&tv,NULL);
   return (int64_t)tv.tv_sec*1000 + tv.tv_usec/1000;
} 
//获取时间戳（秒）
int64_t timestamp_seconds()
{
   struct timeval tv;    
   gettimeofday(&tv,NULL);
   return tv.tv_sec; 
}

std::string getdatetime(int64_t timestamp)
{
    std::string strDate;
    int64_t milli = timestamp+ (int64_t)8*60*60*1000;//此处转化为东八区北京时间，如果是其它时区需要按需求修改
    auto mTime = std::chrono::milliseconds(milli);
    auto tp=std::chrono::time_point<std::chrono::system_clock,std::chrono::milliseconds>(mTime);
    auto tt = std::chrono::system_clock::to_time_t(tp);
    std::tm* now = std::gmtime(&tt);
    char datetime[64];
    sprintf(datetime,"%4d%02d%02d%02d%02d%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday,now->tm_hour,now->tm_min,now->tm_sec);
    strDate=datetime;
    return strDate;
}