#include "mbed.h"
#include "TCPSocketConnection.h"
#include <algorithm>

#include "MTSLog.h"

using namespace mts;

TCPSocketConnection::TCPSocketConnection()
{
}

int TCPSocketConnection::connect(const char* host, const int port)
{
    if (!ip->open(host, port, IPStack::TCP)) {
        return -1;
    }
    return 0;
}

bool TCPSocketConnection::is_connected(void)
{
    return ip->isOpen();
}

int TCPSocketConnection::send(char* data, int length)
{
    Timer tmr;

    if (!_blocking) {
        tmr.start();
        while (tmr.read_ms() < _timeout) {
            if (ip->writeable())
                break;
        }
        if (tmr.read_ms() >= _timeout) {
            return -1;
        }
    }
    return ip->write(data, length, 0);
}

// -1 if unsuccessful, else number of bytes written
int TCPSocketConnection::send_all(char* data, int length)
{
    if (_blocking) {
        return ip->write(data, length, -1);
    } else {
        return ip->write(data, length, _timeout);
    }
}

// -1 if unsuccessful, else number of bytes received
int TCPSocketConnection::receive(char* data, int length)
{
    Timer tmr;
    int bytes = 0;
    int totalbytes = 0;

    if (_blocking) {
        return ip->read(data, length, _timeout);
    } else {
        tmr.start();
        do {
            bytes = ip->read(data + totalbytes, length - totalbytes, 250);
            if (bytes < 0) {
                return -1;
            }
            totalbytes += bytes;
        } while ( tmr.read() < _timeout && totalbytes < length);
        return totalbytes;
    }
}

// -1 if unsuccessful, else number of bytes received
int TCPSocketConnection::receive_all(char* data, int length)
{
    if (_blocking) {
        return ip->read(data, length, -1);
    } else {
        return ip->read(data, length, _timeout);
    }
}
