#include "uptime.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define REQUEST "GET /%s?auto\n"
#define PERROR(c)  do { perror(c); exit(1); } while (0);
#define DIE(fmt, arg...) do { fprintf(stderr, fmt, ##arg); exit(1); } while (0);
#define SHOWUSAGE DIE("Usage: mrtg-apache <machine name> [-p port] [-m multiplier] [-s status-directory] -q\n")
static int quiet = 0;

void print_accesses(char *hostname, int port, char *statusdir, int multiplier)
{
  int s, bytesread;
  char buf[2048], input[256], *p;
  struct sockaddr_in addr;
  struct hostent *h = gethostbyname(hostname);
  unsigned long accesses = 0;

  memset(&addr, 0, sizeof(addr));
  if (!h) {
    if (quiet) {
      printf("0\n");
      return;
    } else {
      DIE("Cannot resolve %s\n", hostname);
    }
  }
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  memcpy(&addr.sin_addr, h->h_addr, sizeof(addr.sin_addr));

  snprintf(buf, sizeof(buf), REQUEST, statusdir);

  if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) PERROR("socket");
  if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) PERROR("connect");
  if (write(s, buf, strlen(buf)+1) < 0) PERROR("write");

  p = buf; *p = 0;
  while ((bytesread = read(s, input, sizeof(input))) > 0) {
    if (sizeof(buf) - (p - buf) > bytesread) {
      memcpy(p, input, bytesread);
      p += bytesread;
    } else {
     /* buffer is not big enough; assume that we've read enough and just 
      * quit
      */
      break;
    }
  }
  if ((p = strstr(buf, "Total Accesses: "))) {
    accesses = strtoul(p + 16, NULL, 0);
  }

  printf("%lu\n", accesses * multiplier);
  
  close(s);
  return;
}

int main(int argc, char **argv)
{
  char *hostname;
  int port = 80;
  int multiplier = 1;
  char *statusdir = "server-status";
  int c;

  while ((c = getopt(argc, argv, "qp:m:s:")) > 0) {
    switch (c) {
      case 'q': quiet = 1; break;
      case 'p': port = atoi(optarg); break;
      case 'm': multiplier = atoi(optarg); break;
      case 's': statusdir = optarg; break;
      default: SHOWUSAGE;
    }
  }
  if (optind >= argc) SHOWUSAGE;
  hostname = argv[optind];

  printf("0\n");
  print_accesses(hostname, port, statusdir, multiplier);
  print_uptime();
  print_hostname();
  return 0;
}
