#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "include/curl/curl.h"

#define MAX_SIZE    1024
struct MemoryStruct {
  char   memory[MAX_SIZE+1];
  size_t loopsize;
};
 
static size_t upd_http_bufwrite(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
 
  printf("Received bytes: %d\n", realsize);
  
  if((mem->loopsize + realsize) > MAX_SIZE) {
     printf("ERROR!! More than %d bytes received.\n", MAX_SIZE);
     return -1;
  }

  memcpy(&(mem->memory[mem->loopsize]), contents, realsize);
  mem->loopsize += realsize;

  return realsize;
}

int main(void)
{
    CURL                  *curl;
    CURLcode              res;
    int                   index = 0;
    char                  range[32] = {0};
    struct MemoryStruct   chunk;
 
    memset(&chunk, 0, sizeof(struct MemoryStruct));
 
    curl_global_init(CURL_GLOBAL_ALL);
 
    /* init the curl session */ 
    curl = curl_easy_init();
      
    if(!curl) {
        printf("Curl error. Return failure\n");
        return -1;
    }

    curl_easy_setopt(curl, CURLOPT_URL, "http://www.microsoft.com");

    /* Define our callback to get called when there's data to be written */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, upd_http_bufwrite);

    /* Set a pointer to our struct to pass to the callback */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

    strcpy(range, "0-1023");

    /* get chunks of MAX_SIZE bytes */
    while((res = curl_easy_setopt(curl, CURLOPT_RANGE, range)) == CURLE_OK) {
        printf("Index %d: Requesting Bytes: %s\n", index, range);

        /* Perform the request, res will get the return code */ 
        res = curl_easy_perform(curl);

        /* Check for completion */ 
        if(res == CURLE_PARTIAL_FILE) {
            printf("File Download Completed\n");
            break;
        }

        /* Check for errors */ 
        if(res != CURLE_OK) {
            printf("curl_easy_perform() failed: %d: %s\n", res, 
                  curl_easy_strerror(res));
            break;
        }

        printf("Bytes received for request range %s: %d\n", range, chunk.loopsize);
        printf("%s", chunk.memory);

        memset(&chunk, 0, sizeof(struct MemoryStruct));

        snprintf(range, sizeof(range) - 1, "%d-%d", (index * MAX_SIZE), (index + 1) * MAX_SIZE - 1);
        range[31] = '\0';

        index++;
    }

    if(curl) {
        curl_easy_cleanup(curl);
    }

    return 0;
}
