#include "ev_dispatch.h"
#include "ev_http.h"
#include <sys/select.h>
#include <errno.h>

using namespace EVD;


// catch SIGINT to kill process 
static void  SIGINT_handler(int sig)
{
  exit(sig);
}

static void run_tests( Dispatch &dispatcher, int count )
{
  time_t start_time = time(NULL);
  int response_count = 0;
  int pfd[2];

  if( pipe( pfd ) ) {
    perror("pipe");
    return;
  }

  // tell the request to stream the response over this file descriptor
  HttpRequest *req = new HttpRequest( dispatcher, "http://www.google.com/", pfd[1] );
  HttpResponse *res = req->m_response;

  dispatcher.request( req );

  // select the response on this thread
  int retval;
  fd_set rd, wr, er;
  struct timeval tv;
  const int read_size = 1024;
  char READ_BUFFER[read_size];
  std::string result_buffer;

  FD_ZERO(&rd);
  FD_ZERO(&wr);
  FD_ZERO(&er);
  FD_SET(pfd[0], &rd);
  tv.tv_sec = 1;
  tv.tv_usec = 0;

  while( (retval = select( pfd[0]+1, &rd, &wr, &er, &tv )) ) {
    if( retval == -1 && errno == EINTR ) { continue; }
    if( retval < 0 ){ perror("select"); break; }
    if( FD_ISSET(pfd[0],&rd) ){
      retval = read(pfd[0],READ_BUFFER,read_size);
      if( retval >= 0 ) {
        result_buffer.append(READ_BUFFER,retval);
        if( retval == 0 ){ break; }
      }
      else {
        perror("read");
        break;
      }
    }
  }
  fprintf( stderr, "loop returnd\n" );
  printf("response: %s, in %.5lf seconds of Content-Length: %d bytes\n%s", res->name.c_str(), res->response_time, result_buffer.length(), res->m_header.c_str() );
  delete res;
}

int main(int argc, char **argv)
{
  Dispatch dispatcher;

  if (signal(SIGINT, SIGINT_handler) == SIG_ERR) {
    printf("SIGINT install error\n");
    exit(1);
  }

  if( !dispatcher.start() ){
    fprintf( stderr, "Failed to start up dispatcher\n" );
    return 1;
  }

  printf( "dispatcher thread running...\n" );

  struct timeval start_time;
  Timer::current_time(&start_time);

  run_tests( dispatcher, 10 );

  printf( "total time: %.5f seconds\n", Timer::elapsed_time( &start_time ) );

  dispatcher.stop();

  return 0;
}