///////////////////////////////////////////////////////////////////////////////
//                                                                           //
// Copyright (C) 2006 by Intel Corporation and Carnegie Mellon University    //
// Contacts: casey.j.helfrich @ intel.com                                    //
//           bdr @ cs.cmu.edu                                                //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#ifndef __NETWORK_H
#define __NETWORK_H

#include <queue>
#include <vector>
#include <string>

#include "GlobalConstants.hxx"
#include "Primitives.hxx"
#include "Clonable.hxx"

class Catom;
class Feature;
class FeatureMap;

using namespace std;

// this can later be changed to swap in ints for the strings as a 
// performance improvement
// premature optimization is the root of all evil
typedef string MailboxID;

class Message : public Clonable {
private:
  
public:
  virtual ~Message() { }

  MailboxID mailboxID;
  featureID arrivalContact;
  Message(MailboxID);

  virtual void* clone() = 0;
};

//////////////////////////////////////////////////////////////////////////
// Network interface
//
// Processes messages flowing through a contact or wireless adaptor
// 
// ***IMPORTANT: This class needs to be locked for concurrent access***

class NetworkAdapter {
private:
  pthread_mutex_t objectMutex;
  void lock();
  void unlock();
  
  unsigned long long remainingBandwidth;
  queue<Message*> messageQueueOut;
  queue<Message*> messageQueueIn;

  catomID hostCatom;
  featureID hostFeature;
  
public:
  NetworkAdapter(catomID CID, featureID FID);
  ~NetworkAdapter();
  
  // adds the appropriate amount of bandwidth for a new tick, then
  // processes any outstanding messages that it can
  void newTick(); 
  
  // called when a message arrives at a catom
  // inserts it into the mailbox for that type of message
  void messageArrived(Message* msg);
  
  // Send message m; asynchronous send
  // Returns false if there's no catom at the other end right now
  // Send may still fail later even if returns true now!
  bool sendMessage(Message* m);
  
  void sendMessages();
  
  unsigned long stats_msgsSent;
  unsigned long stats_msgsRcvd;
};

#endif    /* __NETWORK_H */
