#ifndef INC_HTTP_CPP
#define INC_HTTP_CPP 1

#include "curl/curl.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

/*
 This helper class is used to handle http session and provide the basic send/receive functionalities within http protocal
*/
#define BUFFER_LENGTH  1024*1024

class HttpSession
{
private:
	/*This struct is used to store the soap response message. Assume that the reply message is NOT exceed 1M bytes*/
	struct MemoryStruct
	{
		char buffer[BUFFER_LENGTH];
		size_t size;
	};

  CURL *easyHandle;
  struct curl_slist *headers;
  struct MemoryStruct chunk;
  static size_t writeFunc(void *ptr, size_t size, size_t nmemb, void *data)
  {
     size_t realsize = size*nmemb;
	 struct MemoryStruct *mem = (struct MemoryStruct*)data;
	 /*copy data into memory on special postion*/
	 memcpy((void*)&(mem->buffer[mem->size]),ptr,realsize);
	 mem->size += realsize;	
	 return realsize;
  }

public:

  HttpSession()
  {
	  easyHandle=NULL;
  }
  ~HttpSession()
  {
    if (easyHandle != NULL)
    {
       curl_slist_free_all(headers);    
       curl_easy_cleanup(easyHandle);
    }
  }    
  void init()
  {
	 if (easyHandle == NULL)
     {
        easyHandle = curl_easy_init();
        curl_easy_setopt(easyHandle,CURLOPT_TIMEOUT,30);
		headers = NULL;
        /*Add HTTP header items*/
        headers = curl_slist_append(headers, "Content-Type: text/xml; charset=utf-8");
        headers = curl_slist_append(headers,"SOAPAction: \"http://Kodak.GCRIS.WebService/DoCommand\"");
        headers = curl_slist_append(headers,"Expect: 100-continue");
        /*pass our list of customer header*/   
        curl_easy_setopt(easyHandle,CURLOPT_HTTPHEADER,headers);
     }
  }
  void sendRequest(const char* url, char* message)
  {
     CURLcode ret = CURLE_OK;
     if (easyHandle != NULL)
     {
         /*output the debug info*/
         curl_easy_setopt(easyHandle,CURLOPT_VERBOSE,1);
         /*tell CURL the destination*/
         curl_easy_setopt(easyHandle,CURLOPT_URL,url);
         /*using the POST model to send data*/
         curl_easy_setopt(easyHandle,CURLOPT_POST,1);
         /*tell CURL what message will be sent*/
         curl_easy_setopt(easyHandle,CURLOPT_POSTFIELDS,message);
		 /*set the data pointer and callback function to get http response*/
		 memset(chunk.buffer,0,BUFFER_LENGTH);
		 chunk.size =0;
         curl_easy_setopt(easyHandle,CURLOPT_WRITEDATA,(void *)&chunk);
         curl_easy_setopt(easyHandle,CURLOPT_WRITEFUNCTION,writeFunc);
         /*post message*/
         ret = curl_easy_perform(easyHandle);
		 
		 //printf("Try to print the content:%s\n",buffer);
         if (ret != CURLE_OK) //get error info
            fprintf(stdout, "CURL send message is failed: %d\n", curl_easy_strerror(ret));
      }
      else
          fprintf(stdout, "CURL handle is not initialized!\n");  
  }
  
  char* getReply()
  {
     return chunk.buffer;
  }
  
char* SearchStrFromPeply(const char * left, const char* right)

  {
    char *resultstr=NULL;
    char *lptr = strstr(chunk.buffer, left);
	char *rptr = strstr(chunk.buffer, right);
	//find the pair elements
	if (lptr!=NULL && rptr!=NULL)
	{
	    //move the left point to the first char of element content
		lptr = lptr+strlen(left);
		resultstr=(char*)malloc(rptr-lptr+1);
		memcpy(resultstr,lptr,(rptr-lptr));
        resultstr[rptr-lptr]='\0';
		printf("element content:%s",resultstr);
	}
	return resultstr;
  }


  bool verify_response()
  {
	 bool result = false;
     long status =0;
     if (easyHandle != NULL)
     {
         curl_easy_getinfo(easyHandle,CURLINFO_RESPONSE_CODE,&status);
         if (status==200)
			 result = true;
		 else
			fprintf(stdout, "Something is wrong, the http ret code is:%d\n",status);  	 
     }
     else
           fprintf(stdout, "CURL handle is not initialized!\n");  
	 return result;
  }
};

#endif  