// headers
#include "test.h"
#include "test_libcurl.h"

#pragma comment(lib, "Rpcrt4.lib")

char* subscriptionStr = "";

struct MemoryStruct {
	  char *memory;
	  size_t size;
	};

LibcurlImp::LibcurlImp()
{
	// global libcurl initialisation
	mCurlResult = curl_global_init(CURL_GLOBAL_WIN32);
	if(mCurlResult == 0)
	{
		// start libcurl easy session
		mCurl = curl_easy_init();
	}
}

LibcurlImp::~LibcurlImp()
{
	// global libcurl initialisation
	mCurlResult = curl_global_init(CURL_GLOBAL_WIN32);
	if(mCurlResult == 0)
	{
		// start libcurl easy session
		mCurl = curl_easy_init();
	}
}

size_t  write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
    static int first_time=1;
    char outfilename[FILENAME_MAX] = "body.out";
    static FILE *outfile;
    size_t written;
    if (first_time) {
        first_time = 0;
        outfile = fopen(outfilename,"w");
        if (outfile == NULL) {
            return -1;
        }
        fprintf(stderr,"The body is <%s>\n",outfilename);
    }
    written = fwrite(ptr,size,nmemb,outfile);
    return written;
}

struct WriteThis {
  char *readptr;
  int sizeleft;
};

size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct WriteThis *pooh = (struct WriteThis *)userp;

  if(size*nmemb < 1)
    return 0;

  if(pooh->sizeleft) {
    *(char *)ptr = pooh->readptr[0]; /* copy one single byte */
    pooh->readptr++;                /* advance pointer */
    pooh->sizeleft--;                /* less data left */
    return 1;                        /* we return 1 byte at a time! */
  }

  return -1;                        /* no more data left to deliver */
}

void LibcurlImp::GetEventsFromSource()
 {
	// hello();
	CURLcode res;
	//std::string strHttpContent = "";
	char headerfilename[FILENAME_MAX] = "events.out";
    FILE *headerfile;

	//Generate a UUID to be sent with Subscription query.
	UUID uuid;
	::ZeroMemory(&uuid, sizeof(UUID));
	::UuidCreate(&uuid);
	UCHAR *pszUuid = NULL; 
	::UuidToString(&uuid, &pszUuid);

	char szFormatName[54] = {0};
	sprintf(szFormatName, "%s:%s", "uuid", pszUuid);
	std::string strFormatName(szFormatName);

	std::string strHttpContent="<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:e=\"http://schemas.xmlsoap.org/ws/2004/08/eventing\" xmlns:n=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" xmlns:w=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><s:Header><a:To>http://10.322.251.178:5985/wsman</a:To><w:ResourceURI s:mustUnderstand=\"true\">http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog</w:ResourceURI><a:ReplyTo><a:Address s:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><a:Action s:mustUnderstand=\"true\">http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><w:MaxEnvelopeSize s:mustUnderstand=\"true\">153600</w:MaxEnvelopeSize><a:MessageID>" + strFormatName + "</a:MessageID><w:Locale xml:lang=\"en-US\" s:mustUnderstand=\"false\" /><w:OptionSet xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><w:Option Name=\"SubscriptionName\">RSAenVision</w:Option><w:Option Name=\"ContentFormat\">RenderedText</w:Option><w:Option Name=\"ReadExistingEvents\" xsi:nil=\"true\"/><w:Option Name=\"IgnoreChannelError\" xsi:nil=\"true\"/></w:OptionSet><w:OperationTimeout>PT60.000S</w:OperationTimeout></s:Header><s:Body><e:Subscribe><e:Delivery Mode=\"http://schemas.dmtf.org/wbem/wsman/1/wsman/Pull\"><w:Heartbeats>PT2000.000S</w:Heartbeats><w:Locale xml:lang=\"en-US\"/><w:ContentEncoding>UTF-8</w:ContentEncoding></e:Delivery><w:Filter Dialect=\"http://schemas.microsoft.com/win/2004/08/events/eventquery\"><QueryList><Query Id=\"0\"><Select Path=\"Application\">*</Select><Select Path=\"System\">*</Select><Select Path=\"Security\">*</Select></Query></QueryList></w:Filter><w:SendBookmarks/></e:Subscribe></s:Body></s:Envelope>";

	struct WriteThis pooh;
	pooh.readptr = const_cast<char *>(strHttpContent.c_str());
	pooh.sizeleft = strlen(strHttpContent.c_str());
	//////////////

	struct MemoryStruct chunk;
	chunk.memory=NULL; /* we expect realloc(NULL, size) to work */ 
	chunk.size = 0;    /* no data at this point */ 

	if(mCurlResult == 0)
	{
		// specify the actual URL to deal with
		curl_easy_setopt(mCurl, CURLOPT_URL, "http://10.322.251.178:5985/wsman");

		// set SSH user name and password in libcurl in this format "user:password"
		curl_easy_setopt(mCurl, 
						 CURLOPT_USERPWD,
						 "administrator:password1");

		curl_easy_setopt(mCurl,   CURLOPT_NOPROGRESS  ,1);

		// Tell the library to do a regular HTTP post
		curl_easy_setopt(mCurl, CURLOPT_POST, 1);

		/* we want to use our own read function */
		curl_easy_setopt(mCurl, CURLOPT_READFUNCTION, read_callback);

		/* pointer to pass to our read function */
		curl_easy_setopt(mCurl, CURLOPT_READDATA, &pooh);

		curl_easy_setopt(mCurl, CURLOPT_POSTFIELDSIZE, pooh.sizeleft);

		// Now specify the POST data
		//curl_easy_setopt(mCurl, CURLOPT_POSTFIELDS, strHttpContent);

		// send all data to this function
		curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_data);

		headerfile = fopen(headerfilename,"w");
		if (headerfile == NULL) {
			curl_easy_cleanup(mCurl);
			return;
		}
		curl_easy_setopt(mCurl,   CURLOPT_WRITEHEADER ,headerfile);

		// Perform the request, res will get the return code
		res = curl_easy_perform(mCurl);
	 
		// always cleanup
		curl_easy_cleanup(mCurl);
	}
 }

