#include <stdio.h>
#include <stdlib.h> 
#include <curl/curl.h>
#include <iostream>
#include <sstream>

using namespace std; 

size_t get_url_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
    size_t data_length = size * nmemb;
    ostringstream* oss= (ostringstream*)stream; 
    oss->write((char *)ptr, data_length);
    return data_length;
}


void printLine()
{
  printf("\n");
  for(int i =0 ; i<=80; i++)
    printf("-");
  printf("\n");
}

int main( int argc, char *argv[] )
{
  
  struct timeval t0, t1;
  unsigned long timeout = 500;
  int redirectCnt = 0;
  if ( argc >= 2 ) {
    timeout = atol(argv[1]);   
    if( argc >= 3) {
      int i = atoi(argv[2]);
      if( i > 0) {
         redirectCnt = i;
         printf("setting redirect true with count %d \n", redirectCnt);
      }
    }
  }

  int count = 1;
  if( argc >= 4) { cout << "count -- " << argv[3] << endl ;count =  atoi(argv[3]); }

  CURL *curl;
  CURLcode res;
 
  curl = curl_easy_init();
  if(curl) {
    
  for (int i=0; i<count; i++) {
    printLine();
    char url[200];
    if(redirectCnt>0){
     sprintf(url, "http://127.0.0.1:8080/test_redirectpage.php");
     curl_easy_setopt(curl, CURLOPT_URL, url);
     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
     curl_easy_setopt(curl, CURLOPT_MAXREDIRS, redirectCnt);
    }
    else{
     sprintf(url, "http://127.0.0.1:8080/test.php");
     curl_easy_setopt(curl, CURLOPT_URL, url);
    }
    printf("URL:%s\n",url);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, timeout);
    cout << "setting timeout " << timeout << endl;

    curl_easy_setopt(curl,CURLOPT_VERBOSE,true);
    ostringstream oss(ostringstream::app | ostringstream::trunc);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_url_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &oss);


    gettimeofday(&t0, 0);
    res = curl_easy_perform(curl);
    
    gettimeofday(&t1, 0);
    long long starttime = t0.tv_sec*1000000LL + t0.tv_usec;
    long long endtime = t1.tv_sec*1000000LL + t1.tv_usec;
    long long elapsed = endtime - starttime; 

    printf( "\ntime elapsed %llu \n", elapsed);
    if(res != CURLE_OK) {
      printf("curl_easy_perform() failed code: %d\n", res);
      printf("curl_easy_perform() failed reason: %s\n",
              curl_easy_strerror(res));
      cout << oss.str();
    }else {
      cout << oss.str();
    }
    double _t;
    cout.precision(15);
    if(curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME, &_t) == CURLE_OK)
      cout << "Name lookup time: " << fixed << _t<<endl;
    if(curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &_t) == CURLE_OK)
      cout <<  "Name connect time: " << _t<<endl;
    if(curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &_t) == CURLE_OK)
      cout <<  "Name pretransfer time: " << _t<<endl;
    if(curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &_t) == CURLE_OK)
      cout <<  "Name start transfer time: " << _t<<endl;
    if(curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &_t) == CURLE_OK)
      cout <<  "Name total time: " << _t<<endl;
    if(curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME, &_t) == CURLE_OK)
      cout <<  "Name redirect time: " << _t<<endl;
    printLine();   
  }
    curl_easy_cleanup(curl);
  }
  return 0;
}
