/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "Config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>

#include "Str.h"
#include "system/Net.h"
#include "InputStream.h"


/**
 * Implementation of the InputStream interface. 
 *
 * @see http://www.mmonit.com/
 * @file
 */


/* ----------------------------------------------------------- Definitions */


// One TCP frame data size
#define BUFFER_SIZE 1500

#define T InputStream_T
struct T {
        int fd;
        int offset;
        int length;
        time_t timeout;
        boolean_t isclosed;
        uchar_t buffer[BUFFER_SIZE];
};


/* --------------------------------------------------------------- Private */


/* Fill the internal buffer. Only read once, since we may have read all and an
extra read would just be an extra system call. Returns true (the length of
data read), -1 if an error occured or if the connection was closed by the
client. 0 is returned if a read returned 0 (eof) and read should be retried
because it would block. If an error occured the stream is also set in closed
mode. */
static inline int fill(T S) {
        if (S->isclosed)
                return -1;
        S->length = 0;
        S->offset = 0; 
        errno = 0;
        int n = (int)Net_read(S->fd, S->buffer, BUFFER_SIZE, S->timeout);
        if (n > 0)
                S->length = n;
        else if (n < 0) {
                n = -1; 
                S->isclosed = true; 
                S->offset = S->length = 0;
        } else if (! (errno == EAGAIN || errno == EWOULDBLOCK)) // peer closed connection
                n = -1;
        return n;
}


/* Read a single byte. The byte is returned as an int in the range 0 to 255.
Returns the byte read, or -1 if the end of the stream has been reached or if a
read error occurred */
static inline int read_byte(T S) {
        if (S->offset >= S->length) {
                if (fill(S) <= 0) {
                        return -1;
                }
        }
        return S->buffer[S->offset++];
}


/* ---------------------------------------------------------------- Public */


T InputStream_new(int descriptor) {
        T S;
        NEW(S);
        S->fd = descriptor;
        S->timeout = NET_READ_TIMEOUT;
        return S;
}


void InputStream_free(T *S) {
        assert(S && *S);
        FREE(*S);
}


/* ------------------------------------------------------------ Properties */


int InputStream_getDescriptor(T S) {
        assert(S);
        return S->fd;
}


void InputStream_setTimeout(T S, time_t timeout) {
        assert(S);
        assert(timeout >= 0);
        S->timeout = timeout;
}


time_t InputStream_getTimeout(T S) {
        assert(S);
        return S->timeout;
}


int InputStream_isClosed(T S) {
        assert(S);
        return S->isclosed;
}


int InputStream_buffered(T S) {
        assert(S);
        return S->length - S->offset;
}


/* ---------------------------------------------------------------- Public */


int InputStream_read(T S) {
        assert(S);
        return read_byte(S);
}


char *InputStream_readLine(T S, char *s, int size) { 
        assert(S);
        assert(s);
        uchar_t *p = (uchar_t *)s; 
        for (int c = 0; (--size > 0) && ((c = read_byte(S)) > 0);) { // Stop if \0 is read or no more data
                *p++ = c;
                if (c == '\n')
                        break;
        }
        *p = 0;
        return *s ? s : NULL;
}


int InputStream_readBytes(T S, void *b, int size) {
        assert(S);
        assert(b);
        uchar_t *p = (uchar_t*)b;
        for (int c = 0; (size-- > 0) && ((c = read_byte(S)) != -1);)
                *p++ = c;
        return  S->isclosed ? -1 : (int)(p - (uchar_t*)b);
}


void InputStream_clear(T S) {
        assert(S);
        S->offset = S->length = 0;
}
