#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/un.h>
#include <netdb.h>

#include "OTcp.h"

//----------------------------------------------------------------------

OTcp::OTcp() {
  _rem_bytes = 0;
}

OTcp::~OTcp() {
}

int OTcp::Connect(char * server, int port) {
  int s;
  char buf[100];
  struct sockaddr_in host;
  struct hostent *hp;

  _fd = 0;

  if (server == (char *) 0) {
    gethostname(buf, sizeof(buf));
    server = buf;
  }

  if ((host.sin_addr.s_addr = inet_addr(server)) != -1) {
    host.sin_family = AF_INET;
  } else {
    if ((hp = gethostbyname(server)) != NULL) {
      bzero((char *) &host, sizeof(host));
      bcopy(hp->h_addr, (char *) &host.sin_addr, hp->h_length);
      host.sin_family = hp->h_addrtype;
    } else
      _fd = -2;
  }

  if (!_fd) {
    host.sin_port = (unsigned short) htons(port);
    if ((_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      _fd = -3;
    } else {
      if (connect(_fd, (struct sockaddr *) &host, sizeof(host)) < 0) {
        close(_fd);
        _fd = -4;
      }
    }
  }

  if (_fd < 0) {
    close(_fd);
    printf("Connection failed  server %s port %i error %i.\n", server, port, _fd);
  } else {
    fcntl(_fd, F_SETFL, FNDELAY);
    printf("Connected to %s port %i\n", server, port);
  }
  return _fd;
}

int OTcp::Send(char * message) {
  return(send(_fd, message, strlen(message), 0));
}

int OTcp::Receive() {
  int i;
  char * msg;

  fcntl(_fd, F_SETLK, F_UNLCK);
  _blength = recv(_fd, &(_buffer[_rem_bytes]),
                  TCP_BUFFER_LENGTH-_rem_bytes, 0);
  if (_blength > 0) {
    for(i = 0, msg = _buffer; i<_blength+_rem_bytes; i++) {
      if (_buffer[i] == '\n') {
        _buffer[i] = 0;
        ProcessMessage(msg);
        msg = _buffer + i + 1;
      }
    }

    _rem_bytes += _buffer + _blength - msg;
    for(i = 0; i < _rem_bytes; i++)
      _buffer[i] = msg[i];

    _buffer[_rem_bytes] = 0;
    if (_rem_bytes) {
      Receive();
    }

    return 1;
  } else {
    return 0;
  }
}

int OTcp::ProcessMessage(char * message) {
  printf("(Tcp)msg : %s\n", message);
  return 0;
}
