#include "MessageStatistics.h"
#include <cstddef>
#include <cassert>

MessageStatistics * MessageStatistics::instance = NULL;

MessageStatistics * MessageStatistics::getInstance() {
  if ( !instance )
    instance = new MessageStatistics;
  return instance;
}
void MessageStatistics::deleteInstance() {
  if ( instance )
    delete instance;
  instance = NULL;
}

MessageStatistics::MessageStatistics() {
  reset();
}
MessageStatistics::~MessageStatistics() { /* Empty */ }

unsigned int MessageStatistics::getIndex(MessageType msgType, Direction direction) const {
  assert ( direction == SENT || direction == RCVD );
  unsigned int index = ( direction == SENT ) ? 0u : 1u;
  switch ( msgType ) {
    case ALLELES:
      index += 0u;
      break;
    case LOCAL_STOP:
      index += 2u;
      break;
    case GLOBAL_STOP:
      index += 4u;
      break;
    case LOCAL_SOLUTION:
      index += 6u;
      break;
    case TERMINATION_TOKEN:
      index += 8u;
      break;
    default:
      assert( false );
  }
  assert( index < NUM_MESSAGE_TYPES );
  return index;
}

unsigned int MessageStatistics::getLength() const {
  return NUM_MESSAGE_TYPES;
}

const unsigned int * MessageStatistics::getData() const {
  return data;
}

unsigned int MessageStatistics::get( MessageType msgType, Direction direction ) const {
  return data[ getIndex( msgType, direction ) ];
}

void MessageStatistics::reset( MessageType msgType, Direction direction ) {
  data[ getIndex( msgType, direction ) ] = 0u;
}

void MessageStatistics::reset() {
  for ( unsigned int i = 0u; i < NUM_MESSAGE_TYPES; i++ )
    data[i] = 0u;
}

void MessageStatistics::increment( MessageType msgType, Direction direction, unsigned int amount ) {
  data[ getIndex( msgType, direction ) ] += amount;
}
