/*
 * Copyright (C) 2008 The Trustees of Columbia University in the City of New York. 
 * All rights reserved.
 *
 * See the file LICENSE included in this distribution for details.
 */

#ifndef _KADRTABLE_H
#define _KADRTABLE_H

#include "table.h"

#ifndef _WENGO
#include "types.h"
#include "bigint.h"
#include "msgheader.h"
#include "kaddist.h"
#endif

#ifdef _WENGO
#include "p2pp/common/types.h"
#include "p2pp/bigint/bigint.h"
#include "p2pp/msg/msgheader.h"
#include "p2pp/distance/kaddist.h"
#endif

class KadRTable : public Table {
  

private:
  map <BigInt , list<Internalpeerinfo> > m_RT;
  BigInt m_NodeId;
  BigInt m_Max; //Max distance (set 1 upto length)
 
  uint32 m_HASH_SIZE;
  uint32 m_BASE;
  
  KadDist m_KadDist;
  
  int32 m_iSize;


  //Timers
  uint32 m_BT;
  uint32 m_KArand; //keep-alive randomization
  uint32 m_RTrand; //exchange table randomization
  uint32 m_CTrand; //consistency randomization
  struct timeval m_expCT;

  struct timeval m_expRT;  //routing table timer expired

private:
  void setKATimer(struct timeval& kat);
  void setRTTimer(struct timeval& rttimer);
  void setCTTimer(struct timeval& cttimer);
  int32 isTimerExpired(const struct timeval& rtimer);
  
  int32 routingConsistency();

  int32 FindInsertItr(struct peerinfo& stP, 
    map<BigInt, list<Internalpeerinfo> >::iterator& itr, 
    list<Internalpeerinfo>::iterator& litr,
    int32 updateKA, struct Internalpeerinfo& stIP);
  
public:

  KadRTable();
  ~KadRTable();

  void setNodeId(uchar* peerid, int32 len, int32 base);

  //virtual functions
  uint32 getSize();
  uint32 getNextHop(BigInt, peerinfo&);    
  int32 Insert(struct peerinfo& stP, int32 updateKA);
  int32 Insert(struct peerinfo& stP, int32 updateKA, uint16 stunPort);
  int32 Insert(list<peerinfo>& lstP, int32 updateKA);
  int32 OnTimer();  
  void updateRTT(const struct peerinfo& stP);

  //my function
  uint32 getNextHop(uchar* peerid, uint32 len, struct peerinfo& stP);
  int32 RemovePeer(char8* pchIP, uint32 port);
  int32 RemoveId(uchar* myid, uint32 myidlen);

  int32 getAt(int32 i, struct peerinfo& stP);
  
  virtual int32 getTable(list<peerinfo>& lstP);  
  virtual int32 getTable(list<peerinfo>& lstP, enum transtype tt);
  int32 OnExchangeTable(list<peerinfo>& lstP);
  int32 Find(struct peerinfo& stP);

  void Show();

  void Disconnect();
};

#endif
