#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 = 0;
  tv.tv_usec = 0;

  try {
    while( (retval = select( pfd[0]+1, &rd, &wr, &er, NULL )) ) {
      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;
  }catch(const std::exception &exp){
    perror("select");
  }
  fprintf( stderr, "loop returnd\n" );
}

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;
}