#include <iostream>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <sched.h>
#include <math.h>
#include <sstream>
#include "fs_client.h"

using namespace std;

void fill_buf(char *buf, int size)
{
    int i;
    for (i=0; i<size; i++) {
	//buf[i] = 'a' + random()%26;
	buf[i] = 'b';
    }
}


// assignment methods
void* requester_f(void *req_args);

int status;
char *server;
int server_port;

int main(int argc, char *argv[])
{

    if (argc != 3) {
        cout << "error: usage: " << argv[0] << " <server> <serverPort>\n";
	exit(1);
    }
    server = argv[1];
    server_port = atoi(argv[2]);

  //thread variables
  int numRequesters = 9;
  pthread_t requesters[numRequesters];

  //
  int rc, s, r;

  //create requesters
  for(r = 0; r < numRequesters; r++) {
	
    rc = pthread_create(&requesters[r], NULL, requester_f, (void *) r);
    if (rc) {
      printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1); 
    }
  } 

   pthread_exit(NULL);
  
  return 0;
}

void* requester_f(void *req_args) {

	long l = (long) req_args;
	int i = l;
	
	cout << "!!!! " << i << endl;
	
	int seq1 = 0;
	int seq2 = 0;
	char *password1 = "";
	char *password2 = "";
	
	int session1, session2;
	char buf[1024*1024];
	
	cout << "step 1" << endl;
	
	// itoa
      stringstream f;
      f << i;
      string str = f.str();
      int str_len = str.length() + 1;
      
      char *buff = new char[str_len];
      strncpy(buff, str.c_str(), str_len);
	
	
	cout << "step 2 w/ l: " << str_len << endl;
	
	char *f1 = "file1_";
	char *f2 = "file2_";
	char *u1 = "user1_";
	char *u2 = "user2_";

	char *file1 = (char *)malloc((6+str_len) * sizeof(char) + 1);
	char *file2 = (char *)malloc((6+str_len) * sizeof(char) + 1);
	char *user1 = (char *)malloc((6+str_len) * sizeof(char) + 1);
	char *user2 = (char *)malloc((6+str_len) * sizeof(char) + 1);

	cout << "step 3" << endl;

	strncpy(file1, f1, 6+1);
	strncpy(file2, f2, 6+1);
	strncpy(user1, u1, 6+1);
	strncpy(user2, u2, 6+1);
	
	cout << "step 4" << endl;

    strncat(file1, buff, str_len);
	strncat(file2, buff, str_len);
	strncat(user1, buff, str_len);
	strncat(user2, buff, str_len);
	
	cout << i << " ]# " << seq1 << " creating session for user1 : " << user1 << endl;
	 
    status = fs_session(user1, password1, server, server_port, &session1);
    assert(!status);
    
    //sleep(1);

    cout << i << " ]# " << seq1 << " creating session for user2 : " << user2 << endl;
	
    status = fs_session(user2, password2, server, server_port, &session2);
    assert(!status);

    //sleep(1);

    cout << i << " ]# " << seq1 << " creating file1 : " << file1 << endl;
	
    status = fs_create(user1, password1, session1, seq1++, file1);
    assert(!status);
	
    //sleep(1);
    
    cout << i << " ]# " << seq1 << " adding data to file1 : " << file1 << endl;

    fill_buf(buf, 1024);
    status = fs_append(user1, password1, session1, seq1++, file1, buf, 1024);
    assert(!status);
	
    //sleep(i);
    
    cout << i << " ]# " << seq1 << " creating file2 : " << file2 << endl;

    status = fs_create(user1, password1, session1, seq1++, file2);
    assert(!status);
	
    //sleep(1);
    
    cout << i << " ]# " << seq1 << " adding data to file2 : " << file2 << endl;

    fill_buf(buf, 2000);
    status = fs_append(user1, password1, session1, seq1++, file2, buf, 2000);
    assert(!status);

    //sleep(1);
    
    cout << i << " ]# " << seq1 << " requester complete. " << endl;
  
    sleep(5);

  pthread_exit(NULL);
}


