/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "android/async-utils.h"
#include "android/utils/eintr_wrapper.h"

#ifndef _MSC_VER
#include <unistd.h>
#endif

void
asyncReader_init(AsyncReader* ar,
                 void*        buffer,
                 size_t       buffsize,
                 LoopIo*      io)
{
    ar->buffer   = buffer;
    ar->buffsize = buffsize;
    ar->pos      = 0;
    ar->io       = io;
    if (buffsize > 0)
        loopIo_wantRead(io);
}

AsyncStatus
asyncReader_read(AsyncReader*  ar)
{
    int  ret;

    if (ar->pos >= ar->buffsize) {
        return ASYNC_COMPLETE;
    }

    do {
        ret = HANDLE_EINTR(
                socket_recv(loopIo_fd(ar->io),
                            ar->buffer + ar->pos,
                            ar->buffsize - ar->pos));
        if (ret == 0) {
            /* disconnection ! */
            errno = ECONNRESET;
            return ASYNC_ERROR;
        }
        if (ret < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                loopIo_wantRead(ar->io);
                return ASYNC_NEED_MORE;
            }
            return ASYNC_ERROR;
        }
        ar->pos += ret;

    } while (ar->pos < ar->buffsize);

    loopIo_dontWantRead(ar->io);
    return ASYNC_COMPLETE;
}

void
asyncWriter_init(AsyncWriter*  aw,
                 const void*   buffer,
                 size_t        buffsize,
                 LoopIo*       io)
{
    aw->buffer   = buffer;
    aw->buffsize = buffsize;
    aw->pos      = 0;
    aw->io       = io;
    if (buffsize > 0)
        loopIo_wantWrite(io);
}

AsyncStatus
asyncWriter_write(AsyncWriter* aw)
{
    int  ret;

    if (aw->pos >= aw->buffsize) {
        return ASYNC_COMPLETE;
    }

    do {
        ret = HANDLE_EINTR(
                socket_send(loopIo_fd(aw->io),
                            aw->buffer + aw->pos,
                            aw->buffsize - aw->pos));
        if (ret == 0) {
            /* disconnection ! */
            errno = ECONNRESET;
            return ASYNC_ERROR;
        }
        if (ret < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                return ASYNC_NEED_MORE;
            }
            return ASYNC_ERROR;
        }
        aw->pos += ret;

    } while (aw->pos < aw->buffsize);

    loopIo_dontWantWrite(aw->io);
    return ASYNC_COMPLETE;
}


void
asyncLineReader_init(AsyncLineReader* alr,
                     void*            buffer,
                     size_t           buffsize,
                     LoopIo*          io)
{
    alr->buffer   = buffer;
    alr->buffsize = buffsize;
    alr->pos      = 0;
    alr->io       = io;
    alr->eol      = '\n';
    if (buffsize > 0)
        loopIo_wantRead(io);
}

AsyncStatus
asyncLineReader_read(AsyncLineReader* alr)
{
    int  ret;

    if (alr->pos >= alr->buffsize) {
        errno = ENOMEM;
        return ASYNC_ERROR;
    }

    do {
        char ch;
        ret = HANDLE_EINTR(socket_recv(loopIo_fd(alr->io), &ch, 1));
        if (ret == 0) {
            /* disconnection ! */
            errno = ECONNRESET;
            return ASYNC_ERROR;
        }
        if (ret < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                loopIo_wantRead(alr->io);
                return ASYNC_NEED_MORE;
            }
            return ASYNC_ERROR;
        }
        alr->buffer[alr->pos++] = (uint8_t)ch;
        if (ch == alr->eol) {
            loopIo_dontWantRead(alr->io);
            return ASYNC_COMPLETE;
        }
    } while (alr->pos < alr->buffsize);

    /* Not enough room in the input buffer!*/
    loopIo_dontWantRead(alr->io);
    errno = ENOMEM;
    return ASYNC_ERROR;
}

const char*
asyncLineReader_getLineRaw(AsyncLineReader* alr, int *pLength)
{
    if (alr->pos == 0 || alr->pos > alr->buffsize)
        return NULL;

    if (pLength != 0)
        *pLength = alr->pos;

    return (const char*) alr->buffer;
}

const char*
asyncLineReader_getLine(AsyncLineReader* alr)
{
    /* Strip trailing \n if any */
    size_t  pos = alr->pos;
    char*   buffer = (char*) alr->buffer;

    if (pos == 0 || pos > alr->buffsize)
        return NULL;

    pos--;

    /* Check that we have a proper terminator, and replace it with 0 */
    if (alr->eol == '\n') {
        if (buffer[pos] != '\n')
            return NULL;

        buffer[pos] = '\0';

        /* Also strip \r\n */
        if (pos > 0 && buffer[--pos] == '\r') {
            buffer[pos] = '\0';
        }
    }

    return (const char*) buffer;
}


enum {
    CONNECT_ERROR = 0,
    CONNECT_CONNECTING,
    CONNECT_COMPLETED
};

AsyncStatus
asyncConnector_init(AsyncConnector*    ac,
                    const SockAddress* address,
                    LoopIo*            io)
{
    int ret;
    ac->error = 0;
    ac->io    = io;
    ret = socket_connect(loopIo_fd(io), address);
    if (ret == 0) {
        ac->state = CONNECT_COMPLETED;
        return ASYNC_COMPLETE;
    }
    if (errno == EINPROGRESS || errno == EWOULDBLOCK || errno == EAGAIN) {
        ac->state = CONNECT_CONNECTING;
        /* The socket will be marked writable for select() when the
         * connection is established, or when it is definitely
         * refused / timed-out, for any reason. */
        loopIo_wantWrite(io);
        return ASYNC_NEED_MORE;
    }
    ac->error = errno;
    ac->state = CONNECT_ERROR;
    return ASYNC_ERROR;
}

AsyncStatus
asyncConnector_run(AsyncConnector* ac)
{
    switch (ac->state) {
    case CONNECT_ERROR:
        errno = ac->error;
        return ASYNC_ERROR;

    case CONNECT_CONNECTING:
        loopIo_dontWantWrite(ac->io);
        /* We need to read the socket error to determine if
            * the connection was really succesful or not. This
            * is optional, because in case of error a future
            * socket_recv() or socket_send() will fail anyway, but this
            * allows us to get a better error value as soon as
            * possible.
            */
        ac->error = socket_get_error(loopIo_fd(ac->io));
        if (ac->error == 0) {
            ac->state = CONNECT_COMPLETED;
            return ASYNC_COMPLETE;
        }
        ac->state = CONNECT_ERROR;
        errno = ac->error;
        return ASYNC_ERROR;

    default:
        return ASYNC_COMPLETE;
    }
}

int
asyncConnector_stop(AsyncConnector* ac)
{
    if (ac->state == CONNECT_CONNECTING) {
        loopIo_dontWantWrite(ac->io);
        ac->state = CONNECT_COMPLETED;
        return 0;
    }
    return -1;
}
