/*****************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h> 
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

#include <pthread.h>
#include <stdio.h>
#include <iostream>

struct FtpFile {
  const char *filename;
  FILE *stream;
};

struct threadParam
{
  int threadID;
  int limit;
};

static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
  struct FtpFile *out=(struct FtpFile *)stream;
  if(out && !out->stream) {
    /* open file for writing */
    out->stream=fopen(out->filename, "wb");
    if(!out->stream)
      return -1; /* failure, can't open file to write */
  }
  return fwrite(buffer, size, nmemb, out->stream);
}


void * test_muti(void * arg)
{
  threadParam *pParam = static_cast<threadParam *>(arg);

  int limit = pParam->limit;
  int id    = pParam->threadID;
  
  //write log file in current dir, each thread get one log
  char   buf[20];
  sprintf(buf, "my%d.log\0",id);

  FILE *log = fopen(buf, "wb");
  if(log == NULL){
      fprintf(stderr, "can't open %s\n", buf);
      exit(1);
  }

  CURL *curl;
  CURLcode res;
  struct FtpFile ftpfile={
    "test_local", //local file
    NULL
  };

  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_MAXCONNECTS,1L);

    curl_easy_setopt(curl, CURLOPT_USERNAME, "xiaolech");
    curl_easy_setopt(curl, CURLOPT_PASSWORD, "xiaolech");    
  
    curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PASSWORD);

    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

    int n=1;
  
while(true){ 
  int cur = n++;
  if(cur > limit){
     fprintf(log, "//////////got limit: %d\n", limit);
     break;
   }
     
  fprintf(log, "######this is the %d time########\n", cur);   
  ftpfile.stream=fopen("test_local","wb");
    char *remotePath =  "sftp://zsups118//tmp/huangyal/ftsTest/files/file.12m";
    curl_easy_setopt(curl, CURLOPT_URL, remotePath);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);

   #define RESET_GETONEFILE_OPT \
   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); \
   curl_easy_setopt(curl, CURLOPT_WRITEDATA, stdout); \
   curl_easy_setopt(curl, CURLOPT_URL,"sftp://zsups118"); \
   if (ftpfile.stream) { fclose(ftpfile.stream); }

    res = curl_easy_perform(curl);

    if(CURLE_OK != res) {
      /* we failed */
      fprintf(log, "curl told us %d, in %d time\n", res, cur);
      RESET_GETONEFILE_OPT;
    }
    RESET_GETONEFILE_OPT;

 #undef RESET_GETONEFILE_OPT

  }//end while

  curl_easy_cleanup(curl);

 }

  fprintf(log, "out while end\n");
}


int main(int argc, char** argv)
{

  curl_global_init(CURL_GLOBAL_DEFAULT);

  fprintf(stdout,"Enter main\n");
  
  int loop;
  int NB_THREADS;

  //set the time for which  SFTP operatio will be launched in each thread.
  sscanf(argv[1], "%d", &loop);
  printf("Loop times is %d\n", loop);
  
  //set the number of working threads.
  sscanf(argv[2], "%d", &NB_THREADS);
  printf("Thread number is %d\n", NB_THREADS);

  pthread_t *threadIDs = new pthread_t[NB_THREADS];

  threadParam *tParam = new threadParam[NB_THREADS]; 

  for (int i = 0; i < NB_THREADS; i++)
  {
    tParam[i].limit=loop;  
    tParam[i].threadID = i+1;
    pthread_create(&threadIDs[i], NULL, &test_muti, &tParam[i]);
  }
  
  for (int i = 0; i < NB_THREADS; i++)
  {
    pthread_join(threadIDs[i], NULL);
  }

  delete tParam;
  delete threadIDs;

  curl_global_cleanup();

  printf("main end\n");
  return 0;
}
