#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "hiredis.h"

static char*
type_str(int type)
{
  char *s;

  switch (type) {
  case REDIS_REPLY_STRING:
    s = "STRING";
    break;
  case REDIS_REPLY_ARRAY:
    s = "ARRAY";
    break;
  case REDIS_REPLY_INTEGER:
    s = "INTEGER";
    break;
  case REDIS_REPLY_NIL:
    s = "NIL";
    break;
  case REDIS_REPLY_STATUS:
    s = "STATUS";
    break;
  case REDIS_REPLY_ERROR:
    s = "ERROR";
    break;
  default:
    s = "Unknown type";
  }

  return s;
}

static void
print_reply(redisReply* r, FILE* fp)
{
  fprintf(fp, "REPLY\n");
  fprintf(fp, "  type:     %d (%s)\n", r->type, type_str(r->type));
  fprintf(fp, "  integer:  %lld\n", r->integer);
  fprintf(fp, "  len:      %d\n", r->len);
  if (r->len > 0)
    fprintf(fp, "  str:      '%s'\n", r->str);
  fprintf(fp, "  elements: %d\n", (int )r->elements);

  if (r->type == REDIS_REPLY_ARRAY) {
    int i;
    for (i = 0; i < r->elements; i++) {
      redisReply* e = r->element[i];
      if (e->type == REDIS_REPLY_INTEGER) {
        /* Probably, never come here.*/
        fprintf(fp, "    element[%d]: %lld\n", i, e->integer);
      }
      else {
        if (e->len > 0)
          fprintf(fp, "    element[%d]: '%s'\n", i, e->str);
        else
          fprintf(fp, "    element[%d]: ''\n", i);
      }
    }
  }
}

extern int
main(int argc, char* argv[])
{
  int i;
  redisContext *c;
  redisReply *r;
  char* command;
  char buf[2048];

  if (argc <= 1) {
    fprintf(stderr, "Usage: check \"command\"\n");
    exit(-1);
  }

  buf[0] = '\0';
  for (i = 1; i < argc; i++) {
    if (i > 1) strcat(buf, " ");
    strcat(buf, argv[i]);
  }

  command = buf;
  fprintf(stdout, "COMMAND: '%s'\n", command);

  struct timeval timeout = { 1, 500000 }; // 1.5 seconds
  c = redisConnectWithTimeout((char*)"127.0.0.1", 6379, timeout);
  if (c->err) {
    printf("Connection error: '%s'\n", c->errstr);
    exit(1);
  }

  r = redisCommand(c, command);
  print_reply(r, stdout);

  freeReplyObject(r);

  redisFree(c);

  return 0;
}
