/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** 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 General Public License for more details.
*/
#include "proxy_int.h"
#include "android/sockets.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "android/utils/misc.h"
#include "android/utils/system.h"
#include "android/iolooper.h"
#include <stdlib.h>

int  proxy_log = 0;

void
proxy_LOG(const char*  fmt, ...)
{
    va_list  args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    fprintf(stderr, "\n");
}

void
proxy_set_verbose(int  mode)
{
    proxy_log = mode;
}

/** Global connection list
 **/

static ProxyConnection  s_connections[1];

#define  MAX_HEX_DUMP  512

static void
hex_dump( void*   base, int  size, const char*  prefix )
{
    STRALLOC_DEFINE(s);
    if (size > MAX_HEX_DUMP)
        size = MAX_HEX_DUMP;
    stralloc_add_hexdump(s, base, size, prefix);
    proxy_LOG( "%s", stralloc_cstr(s) );
    stralloc_reset(s);
}

void
proxy_connection_init( ProxyConnection*           conn,
                       int                        socket,
                       SockAddress*               address,
                       ProxyService*              service,
                       ProxyConnectionFreeFunc    conn_free,
                       ProxyConnectionSelectFunc  conn_select,
                       ProxyConnectionPollFunc    conn_poll )
{
    conn->socket    = socket;
    conn->address   = address[0];
    conn->service   = service;
    conn->next      = NULL;

    conn->conn_free   = conn_free;
    conn->conn_select = conn_select;
    conn->conn_poll   = conn_poll;

    socket_set_nonblock(socket);

    {
        SocketType  type = socket_get_type(socket);

        snprintf( conn->name, sizeof(conn->name),
                  "%s:%s(%d)",
                  (type == SOCKET_STREAM) ? "tcp" : "udp",
                  sock_address_to_string(address), socket );

        /* just in case */
        conn->name[sizeof(conn->name)-1] = 0;
    }

    stralloc_reset(conn->str);
    conn->str_pos = 0;
}

void
proxy_connection_done( ProxyConnection*  conn )
{
    stralloc_reset( conn->str );
    if (conn->socket >= 0) {
        socket_close(conn->socket);
        conn->socket = -1;
    }
}


void
proxy_connection_rewind( ProxyConnection*  conn )
{
    stralloc_t*  str = conn->str;

    /* only keep a small buffer in the heap */
    conn->str_pos = 0;
    str->n        = 0;
    if (str->a > 1024)
        stralloc_reset(str);
}

DataStatus
proxy_connection_send( ProxyConnection*  conn, int  fd )
{
    stralloc_t*  str    = conn->str;
    int          avail  = str->n - conn->str_pos;

    conn->str_sent = 0;

    if (avail <= 0)
        return 1;

    if (proxy_log) {
        PROXY_LOG("%s: sending %d bytes:", conn->name, avail );
        hex_dump( str->s + conn->str_pos, avail, ">> " );
    }

    while (avail > 0) {
        int  n = socket_send(fd, str->s + conn->str_pos, avail);
        if (n == 0) {
            PROXY_LOG("%s: connection reset by peer (send)",
                      conn->name);
            return DATA_ERROR;
        }
        if (n < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
                return DATA_NEED_MORE;

            PROXY_LOG("%s: error: %s", conn->name, errno_str);
            return DATA_ERROR;
        }
        conn->str_pos  += n;
        conn->str_sent += n;
        avail          -= n;
    }

    proxy_connection_rewind(conn);
    return DATA_COMPLETED;
}


DataStatus
proxy_connection_receive( ProxyConnection*  conn, int  fd, int  wanted )
{
    stralloc_t*  str    = conn->str;

    conn->str_recv = 0;

    while (wanted > 0) {
        int  n;

        stralloc_readyplus( str, wanted );
        n = socket_recv(fd, str->s + str->n, wanted);
        if (n == 0) {
            PROXY_LOG("%s: connection reset by peer (receive)",
                      conn->name);
            return DATA_ERROR;
        }
        if (n < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
                return DATA_NEED_MORE;

            PROXY_LOG("%s: error: %s", conn->name, errno_str);
            return DATA_ERROR;
        }

        if (proxy_log) {
            PROXY_LOG("%s: received %d bytes:", conn->name, n );
            hex_dump( str->s + str->n, n, "<< " );
        }

        str->n         += n;
        wanted         -= n;
        conn->str_recv += n;
    }
    return DATA_COMPLETED;
}


DataStatus
proxy_connection_receive_line( ProxyConnection*  conn, int  fd )
{
    stralloc_t*  str = conn->str;

    for (;;) {
        char  c;
        int   n = socket_recv(fd, &c, 1);
        if (n == 0) {
            PROXY_LOG("%s: disconnected from server", conn->name );
            return DATA_ERROR;
        }
        if (n < 0) {
            if (errno == EWOULDBLOCK || errno == EAGAIN) {
                PROXY_LOG("%s: blocked", conn->name);
                return DATA_NEED_MORE;
            }
            PROXY_LOG("%s: error: %s", conn->name, errno_str);
            return DATA_ERROR;
        }

        stralloc_add_c(str, c);
        if (c == '\n') {
            str->s[--str->n] = 0;
            if (str->n > 0 && str->s[str->n-1] == '\r')
                str->s[--str->n] = 0;

            PROXY_LOG("%s: received '%s'", conn->name,
                      quote_bytes(str->s, str->n));
            return DATA_COMPLETED;
        }
    }
}

static void
proxy_connection_insert( ProxyConnection*  conn, ProxyConnection*  after )
{
    conn->next        = after->next;
    after->next->prev = conn;
    after->next       = conn;
    conn->prev        = after;
}

static void
proxy_connection_remove( ProxyConnection*  conn )
{
    conn->prev->next = conn->next;
    conn->next->prev = conn->prev;

    conn->next = conn->prev = conn;
}

/** Global service list
 **/

#define  MAX_SERVICES  4

static  ProxyService*  s_services[ MAX_SERVICES ];
static  int            s_num_services;
static  int            s_init;

static void  proxy_manager_atexit( void );

static void
proxy_manager_init(void)
{
    s_init = 1;
    s_connections->next = s_connections;
    s_connections->prev = s_connections;
    atexit( proxy_manager_atexit );
}


extern int
proxy_manager_add_service( ProxyService*  service )
{
    if (!service || s_num_services >= MAX_SERVICES)
        return -1;

    if (!s_init)
        proxy_manager_init();

    s_services[s_num_services++] = service;
    return 0;
}


extern void
proxy_manager_atexit( void )
{
    ProxyConnection*  conn = s_connections->next;
    int               n;

    /* free all proxy connections */
    while (conn != s_connections) {
        ProxyConnection*  next = conn->next;
        conn->conn_free( conn );
        conn = next;
    }
    conn->next = conn;
    conn->prev = conn;

    /* free all proxy services */
    for (n = s_num_services; n-- > 0;) {
        ProxyService*  service = s_services[n];
        service->serv_free( service->opaque );
    }
    s_num_services = 0;
}


void
proxy_connection_free( ProxyConnection*  conn,
                       int               keep_alive,
                       ProxyEvent        event )
{
    if (conn) {
        int  fd = conn->socket;

        proxy_connection_remove(conn);

        if (event != PROXY_EVENT_NONE)
            conn->ev_func( conn->ev_opaque, fd, event );

        if (keep_alive)
            conn->socket = -1;

        conn->conn_free(conn);
    }
}


int
proxy_manager_add( SockAddress*    address,
                   SocketType      sock_type,
                   ProxyEventFunc  ev_func,
                   void*           ev_opaque )
{
    int  n;

    if (!s_init) {
        proxy_manager_init();
    }

    for (n = 0; n < s_num_services; n++) {
        ProxyService*     service = s_services[n];
        ProxyConnection*  conn    = service->serv_connect( service->opaque,
                                                           sock_type,
                                                           address );
        if (conn != NULL) {
            conn->ev_func   = ev_func;
            conn->ev_opaque = ev_opaque;
            proxy_connection_insert(conn, s_connections->prev);
            return 0;
        }
    }
    return -1;
}


/* remove an on-going proxified socket connection from the manager's list.
 * this is only necessary when the socket connection must be canceled before
 * the connection accept/refusal occured
 */
void
proxy_manager_del( void*  ev_opaque )
{
    ProxyConnection*  conn = s_connections->next;
    for ( ; conn != s_connections; conn = conn->next ) {
        if (conn->ev_opaque == ev_opaque) {
            proxy_connection_remove(conn);
            conn->conn_free(conn);
            return;
        }
    }
}

void
proxy_select_set( ProxySelect*  sel,
                  int           fd,
                  unsigned      flags )
{
    if (fd < 0 || !flags)
        return;

    if (*sel->pcount < fd+1)
        *sel->pcount = fd+1;

    if (flags & PROXY_SELECT_READ) {
        FD_SET( fd, sel->reads );
    } else {
        FD_CLR( fd, sel->reads );
    }
    if (flags & PROXY_SELECT_WRITE) {
        FD_SET( fd, sel->writes );
    } else {
        FD_CLR( fd, sel->writes );
    }
    if (flags & PROXY_SELECT_ERROR) {
        FD_SET( fd, sel->errors );
    } else {
        FD_CLR( fd, sel->errors );
    }
}

unsigned
proxy_select_poll( ProxySelect*  sel, int  fd )
{
    unsigned  flags = 0;

    if (fd >= 0) {
        if ( FD_ISSET(fd, sel->reads) )
            flags |= PROXY_SELECT_READ;
        if ( FD_ISSET(fd, sel->writes) )
            flags |= PROXY_SELECT_WRITE;
        if ( FD_ISSET(fd, sel->errors) )
            flags |= PROXY_SELECT_ERROR;
    }
    return flags;
}

/* this function is called to update the select file descriptor sets
 * with those of the proxified connection sockets that are currently managed */
void
proxy_manager_select_fill( int  *pcount, fd_set*  read_fds, fd_set*  write_fds, fd_set*  err_fds)
{
    ProxyConnection*  conn;
    ProxySelect       sel[1];

    if (!s_init)
        proxy_manager_init();

    sel->pcount = pcount;
    sel->reads  = read_fds;
    sel->writes = write_fds;
    sel->errors = err_fds;

    conn = s_connections->next;
    while (conn != s_connections) {
        ProxyConnection*  next = conn->next;
        conn->conn_select(conn, sel);
        conn = next;
    }
}

/* this function is called to act on proxified connection sockets when network events arrive */
void
proxy_manager_poll( fd_set*  read_fds, fd_set*  write_fds, fd_set*  err_fds )
{
    ProxyConnection*  conn = s_connections->next;
    ProxySelect       sel[1];

    sel->pcount = NULL;
    sel->reads  = read_fds;
    sel->writes = write_fds;
    sel->errors = err_fds;

    while (conn != s_connections) {
        ProxyConnection*  next  = conn->next;
        conn->conn_poll( conn, sel );
        conn = next;
    }
}


int
proxy_base64_encode( const char*  src, int  srclen,
                     char*        dst, int  dstlen )
{
    static const char cb64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const char*       srcend = src + srclen;
    int               result = 0;

    while (src+3 <= srcend && result+4 <= dstlen)
    {
        dst[result+0] = cb64[ src[0] >> 2 ];
        dst[result+1] = cb64[ ((src[0] & 3) << 4) | ((src[1] & 0xf0) >> 4) ];
        dst[result+2] = cb64[ ((src[1] & 0xf) << 2) | ((src[2] & 0xc0) >> 6) ];
        dst[result+3] = cb64[ src[2] & 0x3f ];
        src    += 3;
        result += 4;
    }

    if (src < srcend) {
        unsigned char  in[4];

        if (result+4 > dstlen)
            return -1;

        in[0] = src[0];
        in[1] = src+1 < srcend ? src[1] : 0;
        in[2] = src+2 < srcend ? src[2] : 0;

        dst[result+0] = cb64[ in[0] >> 2 ];
        dst[result+1] = cb64[ ((in[0] & 3) << 4) | ((in[1] & 0xf0) >> 4) ];
        dst[result+2] = (unsigned char) (src+1 < srcend ? cb64[ ((in[1] & 0xf) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
        dst[result+3] = (unsigned char) (src+2 < srcend ? cb64[ in[2] & 0x3f ] : '=');
        result += 4;
    }
    return result;
}

int
proxy_resolve_server( SockAddress*   addr,
                      const char*    servername,
                      int            servernamelen,
                      int            serverport )
{
    char  name0[64], *name = name0;
    int   result = -1;

    if (servernamelen < 0)
        servernamelen = strlen(servername);

    if (servernamelen >= sizeof(name0)) {
        AARRAY_NEW(name, servernamelen+1);
    }

    memcpy(name, servername, servernamelen);
    name[servernamelen] = 0;

    if (sock_address_init_resolve( addr, name, serverport, 0 ) < 0) {
        PROXY_LOG("%s: can't resolve proxy server name '%s'",
                  __FUNCTION__, name);
        goto Exit;
    }

    PROXY_LOG("server name '%s' resolved to %s", name, sock_address_to_string(addr));
    result = 0;

Exit:
    if (name != name0)
        AFREE(name);

    return result;
}


int
proxy_check_connection( const char* proxyname,
                        int         proxyname_len,
                        int         proxyport,
                        int         timeout_ms )
{
    SockAddress  addr;
    int          sock;
    IoLooper*    looper;
    int          ret;

    if (proxy_resolve_server(&addr, proxyname, proxyname_len, proxyport) < 0) {
        return -1;
    }

    sock = socket_create(addr.family, SOCKET_STREAM);
    if (sock < 0) {
        PROXY_LOG("%s: Could not create socket !?: %s", __FUNCTION__, errno_str);
        return -1;
    }

    socket_set_nonblock(sock);

    /* An immediate connection is very unlikely, but deal with it, just in case */
    if (socket_connect(sock, &addr) == 0) {
        PROXY_LOG("%s: Immediate connection to %.*s:%d: %s !",
                    __FUNCTION__, proxyname_len, proxyname, proxyport);
        socket_close(sock);
        return 0;
    }

    /* Ok, create an IoLooper object to wait for the connection */
    looper = iolooper_new();
    iolooper_add_write(looper, sock);

    ret = iolooper_wait(looper, timeout_ms);

    iolooper_free(looper);
    socket_close(sock);

    if (ret == 0) {
        errno = ETIMEDOUT;
        ret   = -1;
    }
    return ret;
}
