/* Copyright (C) 2010 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 <unistd.h>

#include "android/sockets.h"
#include "qemu-common.h"
#include "errno.h"
#include "android/iolooper.h"
#include "android/android.h"
#include "android/utils/debug.h"
#include "android/globals.h"
#include "android/utils/system.h"
#include "android/protocol/core-connection.h"

/* Descriptor for a client, connected to the core via console port. */
struct CoreConnection {
    /* Socket address of the console. */
    SockAddress console_address;

    // Helper for performing sync I/O on the console socket.
    SyncSocket* ssocket;

    /* Stream name. Can be:
     *  - NULL for the console itself.
     *  - "attach-UI" for the attached UI client.
     */
    char* stream_name;
};

/*
 * Zero-terminates string buffer.
 * Param:
 *  buf - Buffer containing the string.
 *  buf_size - Buffer size.
 *  eos - String size.
 */
static inline void
_zero_terminate(char* buf, size_t buf_size, size_t eos)
{
    if (eos < buf_size) {
        buf[eos] = '\0';
    } else {
        buf[buf_size - 1] = '\0';
    }
}

/*
 * Checks if console has replied with "OK"
 * Param:
 *  reply - String containing console's reply
 * Return:
 *  boolean: true if reply was "OK", or false otherwise.
 */
static int
_is_reply_ok(const char* reply, int reply_size)
{
    return (reply_size < 2) ? 0 : (reply[0] == 'O' && reply[1] == 'K');
}

/*
 * Checks if console has replied with "KO"
 * Param:
 *  reply - String containing console's reply
 * Return:
 *  boolean: true if reply was "KO", or false otherwise.
 */
static int
_is_reply_ko(const char* reply, int reply_size)
{
    return (reply_size < 2) ? 0 : (reply[0] == 'K' && reply[1] == 'O');
}

SyncSocket*
core_connection_open_socket(SockAddress* sockaddr)
{
    SyncSocket* ssocket;
    int status;
    int64_t deadline;
    char buf[512];

    int fd = socket_create(sock_address_get_family(sockaddr), SOCKET_STREAM);
    if (fd < 0) {
        return NULL;
    }

    socket_set_xreuseaddr(fd);

    // Create sync connection to the console.
    ssocket = syncsocket_connect(fd, sockaddr, CORE_PORT_TIMEOUT_MS);
    if (ssocket == NULL) {
        derror("syncsocket_connect has failed: %s\n", errno_str);
        socket_close(fd);
        return NULL;
    }

    // Upon successful connection the console will reply with two strings:
    // "Android Console....", and "OK\r\n". Read them and check.
    status = syncsocket_start_read(ssocket);
    if (status < 0) {
        derror("syncsocket_start_read has failed: %s\n", errno_str);
        syncsocket_free(ssocket);
        return NULL;
    }

    deadline = iolooper_now() + CORE_PORT_TIMEOUT_MS;
    // Read first line.
    status = syncsocket_read_line_absolute(ssocket, buf, sizeof(buf), deadline);
    if (status <= 0) {
        derror("syncsocket_read_line_absolute has failed: %s\n", errno_str);
        syncsocket_free(ssocket);
        return NULL;
    }
    if (status < 15 || memcmp(buf, "Android Console", 15)) {
        _zero_terminate(buf, sizeof(buf), status);
        derror("console has failed the connection: %s\n", buf);
        syncsocket_free(ssocket);
        return NULL;
    }
    // Read second line
    status = syncsocket_read_line_absolute(ssocket, buf, sizeof(buf), deadline);
    syncsocket_stop_read(ssocket);
    if (status < 2 || !_is_reply_ok(buf, status)) {
        _zero_terminate(buf, sizeof(buf), status);
        derror("unexpected reply from the console: %s\n", buf);
        syncsocket_free(ssocket);
        return NULL;
    }

    return ssocket;
}

CoreConnection*
core_connection_create(SockAddress* console_address)
{
    CoreConnection* desc;
    ANEW0(desc);
    desc->console_address = console_address[0];
    desc->ssocket = NULL;
    desc->stream_name = NULL;

    return desc;
}

void
core_connection_free(CoreConnection* desc)
{
    if (desc == NULL) {
        return;
    }
    if (desc->ssocket != NULL) {
        syncsocket_free(desc->ssocket);
    }
    if (desc->stream_name != NULL) {
        free(desc->stream_name);
    }
    free(desc);
}

int
core_connection_open(CoreConnection* desc)
{
    if (desc == NULL) {
        errno = EINVAL;
        return -1;
    }
    if (desc->ssocket != NULL) {
        return 0;
    }

    desc->ssocket = core_connection_open_socket(&desc->console_address);

    return (desc->ssocket != NULL) ? 0 : -1;
}

void
core_connection_close(CoreConnection* desc)
{
    if (desc == NULL) {
        return;
    }
    if (desc->ssocket != NULL) {
        syncsocket_close(desc->ssocket);
    }
}

int
core_connection_write(CoreConnection* desc,
                      const void* buffer,
                      size_t to_write,
                      size_t* written_bytes)
{
    ssize_t written;

    int status = syncsocket_start_write(desc->ssocket);
    if (status < 0) {
        derror("syncsocket_start_write failed: %s\n", errno_str);
        return status;
    }

    written =
        syncsocket_write(desc->ssocket, buffer, to_write, CORE_PORT_TIMEOUT_MS);
    syncsocket_stop_write(desc->ssocket);
    if (written <= 0) {
        derror("syncsocket_write failed: %s\n", errno_str);
        return -1;
    }
    if (written_bytes != NULL) {
        *written_bytes = written;
    }

    return 0;
}

int
core_connection_read(CoreConnection* desc,
                     void* buffer,
                     size_t to_read,
                     size_t* read_bytes)
{
    ssize_t read_size;

    int status = syncsocket_start_read(desc->ssocket);
    if (status < 0) {
        derror("syncsocket_start_read failed: %s\n", errno_str);
        return status;
    }

    read_size =
        syncsocket_read(desc->ssocket, buffer, to_read, CORE_PORT_TIMEOUT_MS);
    syncsocket_stop_read(desc->ssocket);
    if (read_size <= 0) {
        derror("syncsocket_read failed: %s\n", errno_str);
        return -1;
    }

    if (read_bytes != NULL) {
        *read_bytes = read_size;
    }
    return 0;
}

int
core_connection_switch_stream(CoreConnection* desc,
                              const char* stream_name,
                              char** handshake)
{
    char buf[4096];
    int handshake_len;
    int status;
    int64_t deadline;

    *handshake = NULL;
    if (desc == NULL || desc->stream_name != NULL || stream_name == NULL) {
        errno = EINVAL;
        return -1;
    }

    // Prepare and write "switch" command.
    snprintf(buf, sizeof(buf), "qemu %s\r\n", stream_name);
    if (core_connection_write(desc, buf, strlen(buf), NULL)) {
        return -1;
    }

    // Read result / handshake
    status = syncsocket_start_read(desc->ssocket);
    if (status < 0) {
        return -1;
    }
    deadline = iolooper_now() + CORE_PORT_TIMEOUT_MS;
    handshake_len =
        syncsocket_read_line_absolute(desc->ssocket, buf, sizeof(buf), deadline);
    _zero_terminate(buf, sizeof(buf), handshake_len);
    // Replace terminating "\r\n" with 0
    if (handshake_len >= 1) {
        if (buf[handshake_len - 1] == '\r' || buf[handshake_len - 1] == '\n') {
            buf[handshake_len - 1] = '\0';
            if (handshake_len >= 2 && (buf[handshake_len - 2] == '\r' ||
                                       buf[handshake_len - 2] == '\n')) {
                buf[handshake_len - 2] = '\0';
            }
        }
    }
    // Lets see what kind of response we've got here.
    if (_is_reply_ok(buf, handshake_len)) {
        *handshake = strdup(buf + 3);
        desc->stream_name = strdup(stream_name);
        // We expect an "OK" string here
        status = syncsocket_read_line_absolute(desc->ssocket, buf, sizeof(buf),
                                               deadline);
        syncsocket_stop_read(desc->ssocket);
        if (status < 0) {
            derror("error reading console reply on stream switch: %s\n", errno_str);
            return -1;
        } else if (!_is_reply_ok(buf, status)) {
            _zero_terminate(buf, sizeof(buf), status);
            derror("unexpected console reply when switching streams: %s\n", buf);
            return -1;
        }
        return 0;
    } else if (_is_reply_ko(buf, handshake_len)) {
        derror("console has rejected stream switch: %s\n", buf);
        syncsocket_stop_read(desc->ssocket);
        *handshake = strdup(buf + 3);
        return -1;
    } else {
        // No OK, no KO? Should be an error!
        derror("unexpected console reply when switching streams: %s\n", buf);
        syncsocket_stop_read(desc->ssocket);
        *handshake = strdup(buf);
        return -1;
    }
}

CoreConnection*
core_connection_create_and_switch(SockAddress* console_socket,
                                  const char* stream_name,
                                  char** handshake)
{
    char switch_cmd[256];
    CoreConnection* connection = NULL;

    // Connect to the console service.
    connection = core_connection_create(console_socket);
    if (connection == NULL) {
        return NULL;
    }
    if (core_connection_open(connection)) {
        core_connection_free(connection);
        return NULL;
    }

    // Perform the switch.
    snprintf(switch_cmd, sizeof(switch_cmd), "%s", stream_name);
    if (core_connection_switch_stream(connection, switch_cmd, handshake)) {
        core_connection_close(connection);
        core_connection_free(connection);
        return NULL;
    }

    return connection;
}

void
core_connection_detach(CoreConnection* desc)
{
    core_connection_write(desc, "\n", 1, NULL);
}

int
core_connection_get_socket(CoreConnection* desc)
{
    return (desc != NULL) ? syncsocket_get_socket(desc->ssocket) : -1;
}
