/*
 * client.c: A very, very primitive HTTP client.
 * 
 * To run, try: 
 *      client www.cs.wisc.edu 80 /
 *
 * Sends one HTTP request to the specified HTTP server.
 * Prints out the HTTP response.
 *
 * CS537: For testing your server, you will want to modify this client.  
 * For example:
 * 
 * You may want to make this multi-threaded so that you can 
 * send many requests simultaneously to the server.
 *
 * You may also want to be able to request different URIs; 
 * you may want to get more URIs from the command line 
 * or read the list from a file. 
 *
 * When we test your server, we will be using modifications to this client.
 *
 */

#include "cs537.h"
#define CLIENT_NUM	100

/*
 * Send an HTTP request for the specified file 
 */
void clientSend(int fd, char *filename)
{
  char buf[MAXLINE];
  char hostname[MAXLINE];

  Gethostname(hostname, MAXLINE);

  /* Form and send the HTTP request */
  sprintf(buf, "GET %s HTTP/1.1\n", filename);
  sprintf(buf, "%shost: %s\n\r\n", buf, hostname);
  Rio_writen(fd, buf, strlen(buf));
}
  
/*
 * Read the HTTP response and print it out
 */
void clientPrint(int fd)
{
  rio_t rio;
  char buf[MAXBUF];  
  int length = 0;
  int n;
  
  Rio_readinitb(&rio, fd);

  /* Read and display the HTTP Header */
  n = Rio_readlineb(&rio, buf, MAXBUF);
  while (strcmp(buf, "\r\n") && (n > 0)) {
    printf("Header: %s", buf);
    n = Rio_readlineb(&rio, buf, MAXBUF);

    /* If you want to look for certain HTTP tags... */
    if (sscanf(buf, "Content-Length: %d ", &length) == 1) {
      printf("Length = %d\n", length);
    }
  }

  /* Read and display the HTTP Body */
  n = Rio_readlineb(&rio, buf, MAXBUF);
  while (n > 0) {
    printf("%s", buf);
    n = Rio_readlineb(&rio, buf, MAXBUF);
  }
}

void* thread_code(void *arg);
char *host, *filename;
int port;
char *dynamicFile = "/output.cgi";
char *staticFile1 = "/home.html";
char *staticFile2 = "/p1.html";
char *staticFile3 = "/p2.html";
char *staticFile4 = "/p3.html";
char *staticFile5 = "/p4.html";
char *staticFile6 = "/p5.html";
char *staticFile7 = "/Remzi.html";


int main(int argc, char *argv[])
{
  int num_threads = CLIENT_NUM;
  int rv;

  if (argc != 3) {
    fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]);
    exit(1);
  }

  host = argv[1];
  port = atoi(argv[2]);

/* All File test*/
  pthread_t *clientWorkers1;
  clientWorkers1 = (pthread_t*)malloc(num_threads * sizeof(pthread_t));

  struct timeval startTime3, endTime3;
  double duration3;
  gettimeofday(&startTime3, 0);
  for (int i = 0 ;i < num_threads;i++) {
	  if (i % 8 == 0){
		  if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile1)))
			  printf("cannot create worker thread");
	  }
	  if (i % 8 == 1){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile2)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 2){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile3)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 3){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile4)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 4){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile5)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 5){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile7)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 6){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)staticFile7)))
			printf("cannot create worker thread");
	  }
	  if (i % 8 == 7){
			if ((rv = pthread_create(& clientWorkers1[i], NULL, thread_code, (void*)dynamicFile)))
			printf("cannot create worker thread");
	  }

  }


  for (int i = 0; i < num_threads; i++)
	  pthread_join(clientWorkers1[i], NULL);

  gettimeofday(&endTime3, 0);
  duration3 = (endTime3.tv_sec - startTime3.tv_sec) * 1000000 + (endTime3.tv_usec - startTime3.tv_usec);
  printf("duration: %f(micro-second) \n", duration3);
  printf("Passed All File test\n");

  exit(0);
}

void* thread_code(void *arg){
  /* Open a single connection to the specified host and port */
  int clientfd = Open_clientfd(host, port);
  
  clientSend(clientfd, (char*)arg);
  clientPrint(clientfd);
  Close(clientfd);
}
