/*
 * 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.
 */
#pragma once

#include "android/utils/compiler.h"
#include "android/utils/looper.h"
#include "android/utils/sockets.h"

ANDROID_BEGIN_HEADER

/* A set of useful data types to perform asynchronous operations.
 *
 * IMPORTANT NOTE:
 *    In case of network disconnection, read() and write() just return 0
 *    the first time they are called. As a convenience, these functions
 *    will return ASYNC_ERROR and set 'errno' to ECONNRESET instead.
 */
typedef enum {
    ASYNC_COMPLETE = 0,   /* asynchronous operation completed */
    ASYNC_ERROR,          /* an error occurred, look at errno */
    ASYNC_NEED_MORE       /* more data is needed, try again later */
} AsyncStatus;

/**************************************************************************
 **************************************************************************
 *****
 *****  A S Y N C   R E A D E R
 *****
 *****/

/* An AsyncReader makes it easier to read a given number of bytes into
 * a target buffer asynchronously. Usage is the following:
 *
 * 1/ setup the reader with asyncReader_init(ar, buffer, buffsize,io);
 * 2/ call asyncReader_read(ar, io), where 'io' is a LoopIo whenever
 *    you can receive data, i.e. just after the init() or in your
 *    own callback.
 */
typedef struct {
    uint8_t*  buffer;
    size_t    buffsize;
    size_t    pos;
    LoopIo*   io;
} AsyncReader;

/* Setup an ASyncReader, by giving the address of the read buffer,
 * and the number of bytes we want to read.
 *
 * This also calls loopIo_wantRead(io) for you.
 */
void asyncReader_init(AsyncReader* ar,
                      void*        buffer,
                      size_t       buffsize,
                      LoopIo*      io);

/* Try to read data from 'io' and return the state of the read operation.
 *
 * Returns:
 *    ASYNC_COMPLETE: If the read operation was complete. This will also
 *                    call loopIo_dontWantRead(io) for you.
 *
 *    ASYNC_ERROR: If an error occured (see errno). The error will be
 *                 ECONNRESET in case of disconnection.
 *
 *    ASYNC_NEED_MORE: If there was not enough incoming data to complete
 *                     the read (or if 'events' doesn't contain LOOP_IO_READ).
 */
AsyncStatus  asyncReader_read(AsyncReader*  ar);

/**************************************************************************
 **************************************************************************
 *****
 *****  A S Y N C   W R I T E R
 *****
 *****/

/* An AsyncWriter is the counterpart of an AsyncReader, but for writing
 * data to a file descriptor asynchronously.
 */
typedef struct {
    const uint8_t* buffer;
    size_t         buffsize;
    size_t         pos;
    LoopIo*        io;
} AsyncWriter;

/* Setup an ASyncWriter, by giving the address of the write buffer,
 * and the number of bytes we want to write.
 *
 * This also calls loopIo_wantWrite(io) for you.
 */
void asyncWriter_init(AsyncWriter*  aw,
                      const void*   buffer,
                      size_t        buffsize,
                      LoopIo*       io);

/* Try to write data to 'io' and return the state of the write operation.
 *
 * Returns:
 *    ASYNC_COMPLETE: If the write operation was complete. This will also
 *                    call loopIo_dontWantWrite(io) for you.
 *
 *    ASYNC_ERROR: If an error occured (see errno). The error will be
 *                 ECONNRESET in case of disconnection.
 *
 *    ASYNC_NEED_MORE: If not all bytes could be sent yet (or if 'events'
 *                     doesn't contain LOOP_IO_WRITE).
 */
AsyncStatus asyncWriter_write(AsyncWriter* aw);


/**************************************************************************
 **************************************************************************
 *****
 *****  A S Y N C   L I N E   R E A D E R
 *****
 *****/

/* An AsyncLineReader allows you to read one line of text asynchronously.
 * The biggest difference with AsyncReader is that you don't know the line
 * size in advance, so the object will read data byte-by-byte until it
 * encounters a '\n'.
 */
typedef struct {
    uint8_t*  buffer;
    size_t    buffsize;
    size_t    pos;
    LoopIo*   io;
    char      eol;
} AsyncLineReader;

/* Setup an AsyncLineReader to read at most 'buffsize' characters (bytes)
 * into 'buffer'. The reader will stop when it finds a '\n' which will be
 * part of the buffer by default.
 *
 * NOTE: buffsize must be > 0. If not, asyncLineReader_getLine will return
 *       ASYNC_ERROR with errno == ENOMEM.
 *
 *        buffsize must also sufficiently big to hold the final '\n'.
 *
 * Also calls loopIo_wantRead(io) for you.
 */
void asyncLineReader_init(AsyncLineReader* alr,
                          void*            buffer,
                          size_t           buffsize,
                          LoopIo*          io);

/* Sets line terminator character for the reader.
 * By default, asyncLineReader_init will set EOL to be '\n'. Sometimes it's more
 * convenient to have '\0' as line terminator, so "line" reader easily becomes
 * a "string" reader.
 */
AINLINED void
asyncLineReader_setEOL(AsyncLineReader* alr, char eol)
{
    alr->eol = eol;
}

/* Try to read line characters from 'io'.
 * Returns:
 *    ASYNC_COMPLETE: An end-of-line was detected, call asyncLineReader_getLine
 *                    to extract the line content.
 *
 *    ASYNC_ERROR: An error occured. Note that in case of disconnection,
 *                 errno will be set to ECONNRESET, but you should be able
 *                 to call asyncLineReader_getLine to read the partial line
 *                 that was read.
 *
 *                 In case of overflow, errno will be set to ENOMEM.
 *
 *    ASYNC_NEED_MORE: If there was not enough incoming data (or events
 *                     does not contain LOOP_IO_READ).
 */
AsyncStatus asyncLineReader_read(AsyncLineReader* alr);

/* Return a pointer to the NON-ZERO-TERMINATED line characters, if any.
 * If 'pLength" is not NULL, the function sets '*pLength' to the length
 * in bytes of the line.
 *
 * Returns:
 *    NULL if 'buffsize' was initially 0, otherwise, a pointer to 'buffer'
 *    as passed in asyncLineReader_setup().
 *
 *    NOTE: The data is *not* zero terminated, but its last character
 *           should be '\n' unless an error occured.
 */
const char* asyncLineReader_getLineRaw(AsyncLineReader* alr, int *pLength);

/* Return a pointer to the ZERO-TERMINATED line, with final '\n' or '\r\n'
 * stripped. This will be NULL in case of error though.
 */
const char* asyncLineReader_getLine(AsyncLineReader* alr);

/**************************************************************************
 **************************************************************************
 *****
 *****  A S Y N C   C O N N E C T O R
 *****
 *****/

/* Asynchronous connection to a socket
 */
typedef struct {
    int     error;
    int     state;
    LoopIo* io;
} AsyncConnector;

AsyncStatus
asyncConnector_init(AsyncConnector*    ac,
                    const SockAddress* address,
                    LoopIo*            io);

AsyncStatus
asyncConnector_run(AsyncConnector* ac);

/* Stops connection in progress.
 * Return:
 *  0 if connection in progress has been stopped, or -1 if no connection has been
 *  in progress.
 */
int
asyncConnector_stop(AsyncConnector* ac);

ANDROID_END_HEADER
