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

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif 

#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif

#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif


#include "net.h"
#include "ssl.h"
#include "monit.h"
#include "socket.h"

// libmonit
#include "exceptions/assert.h"
#include "util/Str.h"



/**
 * Implementation of the socket interface.
 * 
 * @file
 */


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


#define TYPE_LOCAL   0
#define TYPE_ACCEPT  1
#define RBUFFER_SIZE 1024

struct Socket_T {
        int port;
        int type;
        int socket;
        char *host;
        Port_T Port;
        int timeout;
        int connection_type;
        ssl_connection *ssl;
        ssl_server_connection *sslserver;
        int length;
        int offset;
        unsigned char buffer[RBUFFER_SIZE+1];
};


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


/*
 * Fill the internal buffer. If an error occurs or if the read
 * operation timed out -1 is returned.
 * @param S A Socket object
 * @param timeout The number of seconds to wait for data to be read
 * @return TRUE (the length of data read) or -1 if an error occured
 */
static int fill(Socket_T S, int timeout) {
        
        int n;
        
        S->offset = 0;
        S->length = 0;
        /* Optimizing, assuming a request/response pattern and that a udp_write
         was issued before we are called, we don't have to wait for data */
        if(S->type == SOCK_DGRAM) timeout = 0; 
        
        /* Read as much as we can, but only block on the first read */
        while(RBUFFER_SIZE > S->length) {
                
                if(S->ssl) {
                        n = recv_ssl_socket(S->ssl, S->buffer + S->length, RBUFFER_SIZE-S->length, timeout);
                } else {
                        n = (int)sock_read(S->socket, S->buffer + S->length,  RBUFFER_SIZE-S->length, timeout);
                }
                
                timeout = 0;
                
                if(n > 0) {
                        S->length += n;
                        continue;
                }  else if(n < 0) {
                        if(errno == EAGAIN || errno == EWOULDBLOCK || S->type == SOCK_DGRAM) break;
                        return -1;
                } else
                        break;
                
        }
        
        return S->length;
        
}


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


Socket_T socket_new(const char *host, int port, int type, int use_ssl, int timeout) {
        Ssl_T ssl = {.use_ssl = use_ssl, .version = SSL_VERSION_AUTO};
        return socket_create_t(host, port, type, ssl, timeout);
}


Socket_T socket_create(void *port) {
        
        int s;
        Port_T p = port;
        
        ASSERT(port);
        
        if((s = create_generic_socket(p)) != -1) {
                
                Socket_T S = NULL;
                
                NEW(S);
                S->socket = s;
                S->length = 0;
                S->offset = 0;
                S->type = p->type;
                S->port = p->port;
                S->timeout = p->timeout;
                S->connection_type = TYPE_LOCAL;
                
                if(p->family == AF_UNIX) {
                        S->host = Str_dup(LOCALHOST);
                } else {
                        S->host = Str_dup(p->hostname);
                }
                
                if(p->SSL.use_ssl && !socket_switch2ssl(S, p->SSL)) {
                        socket_free(&S);
                        return NULL;
                }
                
                S->Port = port;
                return S;
        }
        
        return NULL;
}


Socket_T socket_create_t(const char *host, int port, int type, Ssl_T ssl, int timeout) {
        
        int s;
        int proto = type == SOCKET_UDP ? SOCK_DGRAM : SOCK_STREAM;
        
        ASSERT(host);
        ASSERT((type == SOCKET_UDP)||(type == SOCKET_TCP));
        if(ssl.use_ssl) {
                ASSERT(type == SOCKET_TCP);
        }
        ASSERT(timeout>0);
        
        if((s = create_socket(host, port, proto, timeout)) != -1) {
                
                Socket_T S = NULL;
                
                NEW(S);
                S->socket = s;
                S->port = port;
                S->type = proto;
                S->timeout = timeout;
                S->host = Str_dup(host);
                S->connection_type = TYPE_LOCAL;
                
                if(ssl.use_ssl && !socket_switch2ssl(S, ssl)) {
                        socket_free(&S);
                        return NULL;
                }
                
                return S;
        }
        
        return NULL;
}


Socket_T socket_create_a(int socket, const char *remote_host, int port, void *sslserver) {
        
        Socket_T S;
        
        ASSERT(socket>=0);
        ASSERT(remote_host);
        
        NEW(S);
        S->port = port;
        S->socket = socket;
        S->type = SOCK_STREAM;
        S->timeout = NET_TIMEOUT;
        S->host = Str_dup(remote_host);
        S->connection_type = TYPE_ACCEPT;
        
        if(sslserver) {
                S->sslserver = sslserver;
                if(! (S->ssl = insert_accepted_ssl_socket(S->sslserver))) {
                        goto ssl_error;
                }
                if(! embed_accepted_ssl_socket(S->ssl, S->socket)) {
                        goto ssl_error;
                }
        }
        
        return S;
        
ssl_error:
        socket_free(&S);
        return NULL;
        
}


void socket_free(Socket_T *S) {
        
        ASSERT(S && *S);
        
#ifdef HAVE_OPENSSL
        if((*S)->ssl && (*S)->ssl->handler) {
                if((*S)->connection_type == TYPE_LOCAL) {
                        close_ssl_socket((*S)->ssl);
                        delete_ssl_socket((*S)->ssl);
                } else if((*S)->connection_type == TYPE_ACCEPT && (*S)->sslserver) {
                        close_accepted_ssl_socket((*S)->sslserver, (*S)->ssl);
                }
        } else
#endif
                
                close_socket((*S)->socket);
        FREE((*S)->host);
        FREE(*S);
        
}


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


int socket_is_ready(Socket_T S) {
        
        ASSERT(S);
        
        switch(S->type) {
                        
                case SOCK_STREAM:
                        return check_socket(S->socket);
                        
                case SOCK_DGRAM:
                        return check_udp_socket(S->socket);
                        
                default:
                        break;
        }
        
        return FALSE;
        
}


int socket_is_secure(Socket_T S) {
        
        ASSERT(S);
        
        return (S->ssl != NULL);
        
}


int socket_get_socket(Socket_T S) {
        
        ASSERT(S);
        
        return S->socket;
        
}


int socket_get_type(Socket_T S) {
        
        ASSERT(S);
        
        return S->type;
        
}


void *socket_get_Port(Socket_T S) {
        
        ASSERT(S);
        
        return S->Port;
        
}


int socket_get_remote_port(Socket_T S) {
        
        ASSERT(S);
        
        return S->port;
        
}


const char *socket_get_remote_host(Socket_T S) {
        
        ASSERT(S);
        
        return S->host;
        
}


int socket_get_local_port(Socket_T S) {
        struct sockaddr sock;
        socklen_t len = sizeof(sock);
        
        ASSERT(S);
        
        if(getsockname (S->socket, &sock, &len ) == 0)
                return ntohs (((struct sockaddr_in *)&sock)->sin_port);
        return -1;
        
}


const char *socket_get_local_host(Socket_T S) {
        struct sockaddr sock;
        socklen_t len = sizeof(sock);
        
        ASSERT(S);
        
        if(getsockname(S->socket, &sock, &len) == 0) 
                return inet_ntoa(((struct sockaddr_in *)&sock)->sin_addr);
        return NULL;
        
}


void socket_setError(Socket_T S, const char *error, ...) {
        assert(S);
        assert(error);
        va_list ap;
        va_start(ap, error);
        vsnprintf((char*)S->buffer, RBUFFER_SIZE, error, ap);
        va_end(ap);
}


const char *socket_getError(Socket_T S) {
        assert(S);
        return (const char *)S->buffer;
}


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


int socket_switch2ssl(Socket_T S, Ssl_T ssl)  {
        
        if(! (S->ssl = new_ssl_connection(ssl.clientpemfile, ssl.version)))
                return FALSE;
        
        if(! embed_ssl_socket(S->ssl, S->socket))
                return FALSE;
        
        if(ssl.certmd5 && !check_ssl_md5sum(S->ssl, ssl.certmd5)) {
                LogError("md5sum of certificate does not match!");
                return FALSE;
        }
        
        return TRUE;
}


int socket_print(Socket_T S, const char *m, ...) {
        int n;
        va_list ap;
        char *buf = NULL;
        
        ASSERT(S);
        ASSERT(m);
        
        va_start(ap, m);
        buf = Str_vcat(m, ap);
        va_end(ap);
        
        n = socket_write(S, buf, strlen(buf));
        FREE(buf);
        
        return n;
        
}


int socket_write(Socket_T S, void *b, size_t size) {
        
        ssize_t n = 0;
        void *p = b;
        
        ASSERT(S);
        
        /* Clear any extra data read from the server */
        socket_reset(S);
        
        while(size > 0) {
                
                if(S->ssl) {
                        n = send_ssl_socket(S->ssl, p, size, S->timeout);
                } else {
                        if(S->type == SOCK_DGRAM)
                                n = udp_write(S->socket,  p, size, S->timeout);
                        else
                                n = sock_write(S->socket,  p, size, S->timeout);
                }
                
                if(n <= 0) break;
                p += n;
                size -= n;
                
        }
        
        if(n < 0) {
                /* No write or a partial write is an error */
                return -1;
        }
        
        return  (int)(p - b);
        
}


int socket_read_byte(Socket_T S) {
        
        ASSERT(S);
        
        if(S->offset >= S->length) {
                if(fill(S, S->timeout) <= 0)
                        return -1;
        }
        
        return S->buffer[S->offset++];
        
}


int socket_read(Socket_T S, void *b, int size) {
        
        int c;
        unsigned char *p = b;
        
        ASSERT(S);
        
        while((size-- > 0) && ((c = socket_read_byte(S)) >= 0)) { 
                *p++ = c;
        }
        
        return  (int)((long)p - (long)b);
        
}


char *socket_readln(Socket_T S, char *s, int size) {
        
        int c;
        unsigned char *p = (unsigned char *)s;
        
        ASSERT(S);
        
        while(--size && ((c = socket_read_byte(S)) > 0)) { // Stop when \0 is read
                *p++ = c;
                if(c == '\n')
                        break;
        }
        
        *p = 0;
        
        if(*s)
                return s;
        
        return NULL;
        
}


void socket_reset(Socket_T S) {
        
        ASSERT(S);
        
        /* Throw away any pending incomming data */
        while(fill(S, 0) > 0);
        S->offset = 0;
        S->length = 0;
        
}


int socket_shutdown_write(Socket_T S) {
        ASSERT(S);
        return (shutdown(S->socket, 1) == 0);
}
