/*
 * Libcurl-7.59 test program. Based on libcurl example "getinmemory.c".
 * Target source file: lib/imap.c
 *
 * May 8 2018 By Kinglt, kinglotterry@163.com.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>

struct MemoryStruct {
	char *memory;
	size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
	size_t realsize = size * nmemb;
	struct MemoryStruct *mem = (struct MemoryStruct *)userp;
	mem->memory = realloc(mem->memory, mem->size + realsize);
	memcpy(&(mem->memory[mem->size]), contents, realsize);
	mem->size += realsize;
	mem->memory[mem->size] = '\0';
	return realsize;
}

int main()
{
	CURLcode err;

	/* show libcurl version */
	curl_version_info_data *ver;
	ver = curl_version_info(CURLVERSION_NOW);
	printf("libcurl version : %s\n------------------\n", ver->version);

	/* init libcurl */
	CURL *chdl;
	chdl = curl_easy_init();
	curl_easy_setopt(chdl, CURLOPT_VERBOSE, 1);

	/* Test 1:*/
	printf("check 'imap://.../inbox/;uid=UID' fetch (return to continue)");
	printf("\n---------------------------------\n");
	getchar();
	curl_easy_setopt(chdl, CURLOPT_URL,
			  "imap://user:password@example.com/INBOX/;UID=123");
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK){
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		if (err != CURLE_REMOTE_FILE_NOT_FOUND)
			return 1;
	}
	
	/* Test 2: */
	printf("\ncheck 'imap://.../inbox/;uid=MSN'(sequence number) fetch (return to continue)");
	printf("\n---------------------------------\n");
	getchar();
	curl_easy_setopt(chdl, CURLOPT_URL,
			  "imap://user:password@example.com/INBOX/;UID=2");
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK){
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		if (err != CURLE_REMOTE_FILE_NOT_FOUND)
			return 2;
	}
	
	/* Test 3: */
	printf("\ncheck CUSTOMREQUEST's search-fetch-writeback (return to continue)");
	printf("\n---------------------------------\n");
	getchar();

	int no = 0;
	char cmd[200];
	struct MemoryStruct chunk;
	chunk.memory = malloc(1);
	chunk.size = 0; 
	chunk.memory[0] = '\0';

	/* search */
	curl_easy_setopt(chdl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
	curl_easy_setopt(chdl, CURLOPT_WRITEDATA, (void *)&chunk);
	curl_easy_setopt(chdl, CURLOPT_CUSTOMREQUEST, "SEARCH SUBJECT test");
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK) {
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		return 3;
	}

	/* fetch & writeback */
	sscanf(chunk.memory, "%*s%*s%d", &no);
	sprintf(cmd, "FETCH %d BODY[TEXT]", no);
	curl_easy_setopt(chdl, CURLOPT_CUSTOMREQUEST, cmd);
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK) {
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		return 4;
	}

	printf("\n---------------------------------\n");
	printf("\nreceived %d bytes: %s\n", chunk.size, chunk.memory);

	/* Test 4: */
	printf("\ncheck CUSTOMREQUEST's UID search-fetch-writeback (return to continue)");
	printf("\n---------------------------------\n");
	getchar();

	chunk.memory = realloc(chunk.memory, 1);
	chunk.size = 0; 
	chunk.memory[0] = '\0';

	/* uid search */
	curl_easy_setopt(chdl, CURLOPT_CUSTOMREQUEST,"UID SEARCH SUBJECT test");
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK) {
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		return 5;
	}

	/* uid fetch & writeback */
	sscanf(chunk.memory, "%*s%*s%d", &no);
	sprintf(cmd, "UID FETCH %d BODY[TEXT]", no);
	curl_easy_setopt(chdl, CURLOPT_CUSTOMREQUEST, cmd);
	err = curl_easy_perform(chdl);
   	if (err != CURLE_OK) {
		fprintf(stderr, "error : %s\n", curl_easy_strerror(err));
		return 6;
	}

	printf("\n---------------------------------\n");
	printf("\nreceived %d bytes: %s\n", chunk.size, chunk.memory);

	curl_easy_cleanup(chdl);
	
	return 0;
}
