#include "tcpconnection.h"

tcpconnection::tcpconnection()
{
  ready = 0;
  sock = 0;
}

tcpconnection::~tcpconnection()
{
  closesocket();
}

int tcpconnection::init( int s, sockaddr_in &add )
{
  closesocket();
  sock = s;
  address = add;
  ready = 1;
  return 0;
}

int tcpconnection::closesocket()
{
  if(ready == 1)
    {
      std::cout << "closing " << sock << "\n";
      close( sock );
      sock = 0;
      ready = 0;
    }
  return 0;
}

int tcpconnection::sendmessage( int id, int sz, char *buf )
{
  char *d;
  d = new char[(sizeof(int)*2)+sz];
  memcpy( d, &id, sizeof(int) );
  memcpy( d+sizeof(int), &sz, sizeof(int) );
  if( sz > 0 )
    memcpy( d+(2*sizeof(int)), buf, sz );
  int ret;
  ret = write( d, sizeof(int)*2+sz );
  delete [] d;
  return ret;
}

int tcpconnection::write( char *buf, int size )
{
  int sent, ts;
  sent = 0;

  if( size == sizeof(int) )
    {
      int *t;
      t = (int*) buf;
      if( *t == 2 )
        std::cout << "WARNING EXIT FLAG SENT\n";
    }
  while( sent < size )
    {
      ts = send(sock, buf+sent, size-sent, 0);
      if( ts < 0 )
        {
          std::cout << "send failed " << sock << "\n";
          return -1;
        }
     
      sent = sent + ts;
    }
  return 0;
}

int tcpconnection::read( char *buf, int size )
{
  int rev, ts;
  rev = 0;
  while( rev < size )
    {
      ts = recv(sock, buf+rev, size-rev, 0);
      if( ts <= 0 )
        {
          std::cout << "read failed on " << sock <<" " << ts << "\n";
          std::cout << "trying to read: " << size << " bytes\n";
          return -1;
        }
        
      rev = rev + ts;
    }
  return 0;
}

int tcpconnection::init( std::string ip, int port )
{
  closesocket();

  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
      std::cout << "socket() failed\n";
      return -1;
    }

  address.sin_family = AF_INET;
  address.sin_addr.s_addr = inet_addr( ip.c_str() );
  address.sin_port = htons(port);
  
  /* Establish the connection to the echo server */
  if ( connect(sock, (struct sockaddr *) &address, sizeof(address)) < 0 )
    {
      std::cout << "connect() failed\n";
      return -1;
    }
  std::cout << "connected to: " << ip << ":" << port << "\n";
  std::cout << "socket: " << sock << "\n";
  ready = 1;
  return 0;
}
