/*******************************************************************
 *                  Light Weight Chord Library 1.0                 *
 *  CopyRight(C) Yoshihide Matsumoto IDEON WorkingGroup 2003,2004  *
 *      matsumoto333@yahoo.co.jp (http://www.matchan.mydns.jp)     *
 *                                                                 *
 * Implementation of chord (Distributed Hash Table)                *
 * This program is distributed under GPL                           *
 * Light Weight Chord Library comes with ABSOLUTELY NO WARRANTY.   *
 * This is free software, and you are welcome to redistribute it   *
 * under certain conditions; read `COPYING' for details.           *
 *******************************************************************/

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>			// For RAND_MAX, SYSTEM
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>			// For isalnum() and isspace()
#include <time.h>//random
#include <stdarg.h>//fmt
#include "misc.h"
#include "mchord.h"                     //GetLogFlg()

extern MChord *pMChord;

void ip_to_str(unsigned int ip, char *a)
{

   struct in_addr ia;
   
   ia.s_addr = htonl(ip);
   snprintf(a, 32, "%s", inet_ntoa(ia));

}


unsigned int str_to_ip(char *str)
{
   struct in_addr ia;
   int r;
   r = inet_aton(str, &ia);
   if (r)
     return ntohl(ia.s_addr);
   
   return 0;
}

void print_ip(int ip, int port){

  char buff[32];
  ip_to_str(ip, buff);

  log(NOTICE, "IP=[%s:%d]\n", buff, port);
}

unsigned int get_random(){

  return (unsigned int)((RAND_MAX + 1.0) * rand() /(RAND_MAX + 1.0));
  
}

void init_random(){

  FILE *fp;
  int rnd;
  fp = fopen("/dev/random","r");
  fread(&rnd,1,4,fp);

  //srand((unsigned int)time(NULL));
  srand((unsigned int)rnd);
  
}

//easy hash function
//TODO: going to change to sha-1
int mhash(char *data, int size){

  int cnt = 0;
  int out = 0;
  int tmp;

  //fprintf(stderr, "[%d][%s]\n",size, data);
  if(size <= 4){
    memcpy(&out, data, size);
    //fprintf(stderr, "OK1 ret=%d\n", out);

  }else{
    //fprintf(stderr, "OK2 ret=%d\n", out);
    while(cnt <= (size - 4)){
      memcpy(&tmp, &data[cnt], 4);

      //fprintf(stderr, "OK3 ret = %d,%d\n", cnt, size);
      out = out + tmp;
      cnt++;
    }
  }

  //fprintf(stderr, "ret=%d\n", out);
  return out;
  
}



void file_delete(char *fname){
  char command[120];
  sprintf(command,"rm %s\n",fname);
  system(command);

}

void debug(char *data){
   fprintf(stderr,"[%s]\n",data);
}



void log(int level, char *fmt,...){

  char file_name[50];
  FILE *fp;

  va_list ap;
  va_start(ap, fmt);

  //set fp
  if(pMChord->GetLogFlg() == 1){
    fp = stderr;
  }else{
    sprintf(file_name,"./%d.log", pMChord->GetPort());
    fp = fopen(file_name, "a");
    if(fp == NULL){
      fprintf(stderr, "mchord: cannot open file = %s\n", file_name);
      return;
    }
    
  }
  
  
  switch(level){
  case ERROR:
    fprintf(fp, "ERR:");
    break;

  case WARNING:
    fprintf(fp, "WARN:");
    break;

  case INFORMATION:
    fprintf(fp, "INFO:");
    break;

  case NOTICE:
    fprintf(fp, "NOTI:");
    break;

  case NOTIMPLEMENTED:
    fprintf(fp, "NIMP:");
    break;
    
  default:
    fprintf(fp, "UNKWON:");
    break;
    
  }
  vfprintf(fp, fmt, ap);
  
  if(pMChord->GetLogFlg() == 1){
    fclose(fp);
  }
  
}
