/*
 * 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.
 */

/*
 * Contains helper routines dealing with syncronous access to a non-blocking
 * sokets.
 */

#include "qemu-common.h"
#include "errno.h"
#include "android/iolooper.h"
#include "android/sockets.h"
#include "android/utils/debug.h"
#include "android/sync-utils.h"
#include "android/utils/system.h"

#define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)

struct SyncSocket {
    // Helper for performing synchronous I/O on the socket.
    IoLooper* iolooper;

    /* Opened socket handle. */
    int fd;
};

SyncSocket*
syncsocket_init(int fd)
{
    SyncSocket* sync_socket;
    ANEW0(sync_socket);

    socket_set_nonblock(fd);
    sync_socket->iolooper = iolooper_new();
    sync_socket->fd = fd;

    return sync_socket;
}

SyncSocket*
syncsocket_connect(int fd, SockAddress* sockaddr, int timeout)
{
    IoLooper* looper;
    int connect_status;
    SyncSocket* sync_socket = NULL;

    socket_set_nonblock(fd);

    for(;;) {
        connect_status = socket_connect(fd, sockaddr);
        if (connect_status >= 0) {
            // Connected. Create IoLooper for the helper.
            looper = iolooper_new();
            break;
        }

        if (errno == EINPROGRESS || errno == EAGAIN || errno == EWOULDBLOCK) {
            // Connection is in progress. Wait till it's finished.
            looper = iolooper_new();
            iolooper_add_write(looper, fd);
            connect_status = iolooper_wait(looper, timeout);
            if (connect_status > 0) {
                iolooper_del_write(looper, fd);
                break;
            } else {
                iolooper_free(looper);
                return NULL;
            }
        } else {
            return NULL;
        }
    }

    // We're now connected. Lets initialize SyncSocket instance
    // for this connection.
    sync_socket = malloc(sizeof(SyncSocket));
    if (sync_socket == NULL) {
        derror("PANIC: not enough memory\n");
        exit(1);
    }

    sync_socket->iolooper = looper;
    sync_socket->fd = fd;

    return sync_socket;
}

void
syncsocket_close(SyncSocket* ssocket)
{
    if (ssocket != NULL && ssocket->fd >= 0) {
        if (ssocket->iolooper != NULL) {
            iolooper_reset(ssocket->iolooper);
        }
        socket_close(ssocket->fd);
        ssocket->fd = -1;
    }
}

void
syncsocket_free(SyncSocket* ssocket)
{
    if (ssocket != NULL) {
        if (ssocket->iolooper != NULL) {
            iolooper_free(ssocket->iolooper);
        }
        free(ssocket);
    }
}

int
syncsocket_start_read(SyncSocket* ssocket)
{
    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }
    iolooper_add_read(ssocket->iolooper, ssocket->fd);
    return 0;
}

int
syncsocket_stop_read(SyncSocket* ssocket)
{
    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }
    iolooper_del_read(ssocket->iolooper, ssocket->fd);
    return 0;
}

int
syncsocket_start_write(SyncSocket* ssocket)
{
    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }
    iolooper_add_write(ssocket->iolooper, ssocket->fd);
    return 0;
}

int
syncsocket_stop_write(SyncSocket* ssocket)
{
    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }
    iolooper_del_write(ssocket->iolooper, ssocket->fd);
    return 0;
}

ssize_t
syncsocket_read_absolute(SyncSocket* ssocket,
                         void* buf,
                         size_t size,
                         int64_t deadline)
{
    int ret;

    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }

    ret = iolooper_wait_absolute(ssocket->iolooper, deadline);
    if (ret > 0) {
        if (!iolooper_is_read(ssocket->iolooper, ssocket->fd)) {
            D("%s: Internal error, iolooper_is_read() not set!", __FUNCTION__);
            return -1;
        }
        ret = socket_recv(ssocket->fd, buf, size);
    } else if (ret == 0) {
        // Timed out
        errno = ETIMEDOUT;
        ret = -1;
    }
    return ret;
}

ssize_t
syncsocket_read(SyncSocket* ssocket, void* buf, size_t size, int timeout)
{
    return syncsocket_read_absolute(ssocket, buf, size, iolooper_now() + timeout);
}

ssize_t
syncsocket_write_absolute(SyncSocket* ssocket,
                          const void* buf,
                          size_t size,
                          int64_t deadline)
{
    int ret;
    size_t written = 0;

    if (ssocket == NULL || ssocket->fd < 0 || ssocket->iolooper == NULL) {
        errno = EINVAL;
        return -1;
    }

    do {
        ret = iolooper_wait_absolute(ssocket->iolooper, deadline);
        if (ret < 0) {
            return ret;
        } else if (ret == 0) {
            // Timeout.
            errno = ETIMEDOUT;
            return -1;
        }
        if (!iolooper_is_write(ssocket->iolooper, ssocket->fd)) {
            D("%s: Internal error, iolooper_is_write() not set!", __FUNCTION__);
            return -1;
        }

        ret = socket_send(ssocket->fd, (const char*)buf + written, size - written);
        if (ret > 0) {
            written += ret;
        } else if (ret < 0) {
            if (errno != EAGAIN && errno != EWOULDBLOCK) {
                return -1;
            }
        } else {
            // Disconnected.
            errno = ECONNRESET;
            return -1;
        }
    } while (written < size);
    return (int)written;
}

ssize_t
syncsocket_write(SyncSocket* ssocket, const void* buf, size_t size, int timeout)
{
    return syncsocket_write_absolute(ssocket, buf, size, iolooper_now() + timeout);
}

ssize_t
syncsocket_read_line_absolute(SyncSocket* ssocket,
                              char* buffer,
                              size_t size,
                              int64_t deadline)
{
    size_t read_chars = 0;

    while (read_chars < size) {
        char ch;
        int ret = syncsocket_read_absolute(ssocket, &ch, 1, deadline);
        if (ret <= 0) {
            return ret;
        }
        buffer[read_chars++] = ch;
        if (ch == '\n') {
            return read_chars;
        }
    }

    /* Not enough room in the input buffer!*/
    errno = ENOMEM;
    return -1;
}

ssize_t
syncsocket_read_line(SyncSocket* ssocket, char* buffer, size_t size, int timeout)
{
    return syncsocket_read_line_absolute(ssocket, buffer, size,
                                         iolooper_now() + timeout);
}

int
syncsocket_get_socket(SyncSocket* ssocket)
{
    return (ssocket != NULL) ? ssocket->fd : -1;
}
