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

/*
 * Contains the UI-side implementation of the "ui-core-control" service that is
 * part of the UI control protocol. Here we send UI control commands to the Core.
 */

#include "ui/console.h"
#include "android/looper.h"
#include "android/async-utils.h"
#include "android/sync-utils.h"
#include "android/utils/debug.h"
#include "android/utils/panic.h"
#include "android/protocol/core-connection.h"
#include "android/protocol/core-commands.h"
#include "android/protocol/core-commands-proxy.h"
#include "android/protocol/core-commands-api.h"

/* Descriptor for the UI-side "ui-core-control" service. */
typedef struct CoreCmdProxy {
    /* Core connection established for this service. */
    CoreConnection*     core_connection;

    /* Socket descriptor for the UI service. */
    int                 sock;

    /* Socket wrapper for sync srites. */
    SyncSocket*         sync_writer;

    /* Socket wrapper for sync reads. */
    SyncSocket*         sync_reader;
} CoreCmdProxy;

/* One and only one CoreCmdProxy instance. */
static CoreCmdProxy  _coreCmdProxy = { 0 };

/* Sends UI command to the core.
 * Param:
 *  cmd_type, cmd_param, cmd_param_size - Define the command.
 * Return:
 *  0 On success, or < 0 on failure.
 */
static int
_coreCmdProxy_send_command(uint8_t cmd_type,
                           void* cmd_param,
                           uint32_t cmd_param_size)
{
    int status;
    UICmdHeader header;

    // Prepare the command header.
    header.cmd_type = cmd_type;
    header.cmd_param_size = cmd_param_size;
    status = syncsocket_start_write(_coreCmdProxy.sync_writer);
    if (!status) {
        // Send the header.
        status = syncsocket_write(_coreCmdProxy.sync_writer, &header,
                                  sizeof(header),
                                  core_connection_get_timeout(sizeof(header)));
        // If there is request data, send it too.
        if (status > 0 && cmd_param != NULL && cmd_param_size > 0) {
            status = syncsocket_write(_coreCmdProxy.sync_writer, cmd_param,
                                      cmd_param_size,
                                      core_connection_get_timeout(cmd_param_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_write(_coreCmdProxy.sync_writer);
    }
    if (status < 0) {
        derror("Unable to send UI control command %d (size %u): %s\n",
                cmd_type, cmd_param_size, errno_str);
    }
    return status;
}

/* Reads UI control command response from the core.
 * Param:
 *  resp - Upon success contains command response header.
 *  resp_data - Upon success contains allocated reponse data (if any). The caller
 *      is responsible for deallocating the memory returned here.
 * Return:
 *  0 on success, or < 0 on failure.
 */
static int
_coreCmdProxy_get_response(UICmdRespHeader* resp, void** resp_data)
{
    int status =  syncsocket_start_read(_coreCmdProxy.sync_reader);
    if (!status) {
        // Read the header.
        status = syncsocket_read(_coreCmdProxy.sync_reader, resp,
                                 sizeof(UICmdRespHeader),
                                 core_connection_get_timeout(sizeof(UICmdRespHeader)));
        // Read response data (if any).
        if (status > 0 && resp->resp_data_size) {
            *resp_data = malloc(resp->resp_data_size);
            if (*resp_data == NULL) {
                APANIC("_coreCmdProxy_get_response is unable to allocate response data buffer.\n");
            }
            status = syncsocket_read(_coreCmdProxy.sync_reader, *resp_data,
                                     resp->resp_data_size,
                                     core_connection_get_timeout(resp->resp_data_size));
        }
        status = syncsocket_result(status);
        syncsocket_stop_read(_coreCmdProxy.sync_reader);
    }
    if (status < 0) {
        derror("Unable to get UI command response from the Core: %s\n",
               errno_str);
    }
    return status;
}

int
corecmd_set_coarse_orientation(AndroidCoarseOrientation orient)
{
    UICmdSetCoarseOrientation cmd;
    cmd.orient = orient;
    return _coreCmdProxy_send_command(AUICMD_SET_COARSE_ORIENTATION,
                                      &cmd, sizeof(cmd));
}

int
corecmd_toggle_network()
{
    return _coreCmdProxy_send_command(AUICMD_TOGGLE_NETWORK, NULL, 0);
}

int
corecmd_trace_control(int start)
{
    UICmdTraceControl cmd;
    cmd.start = start;
    return _coreCmdProxy_send_command(AUICMD_TRACE_CONTROL,
                                      &cmd, sizeof(cmd));
}

int
corecmd_is_network_disabled()
{
    UICmdRespHeader resp;
    void* tmp = NULL;
    int status;

    status = _coreCmdProxy_send_command(AUICMD_CHK_NETWORK_DISABLED, NULL, 0);
    if (status < 0) {
        return status;
    }
    status = _coreCmdProxy_get_response(&resp, &tmp);
    if (status < 0) {
        return status;
    }
    return resp.result;
}

int
corecmd_get_netspeed(int index, NetworkSpeed** netspeed)
{
    UICmdGetNetSpeed req;
    UICmdRespHeader resp;
    UICmdGetNetSpeedResp* resp_data = NULL;
    int status;

    // Initialize and send the query.
    req.index = index;
    status = _coreCmdProxy_send_command(AUICMD_GET_NETSPEED, &req, sizeof(req));
    if (status < 0) {
        return status;
    }

    // Obtain the response from the core.
    status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
    if (status < 0) {
        return status;
    }
    if (!resp.result) {
        NetworkSpeed* ret;
        // Allocate memory for the returning NetworkSpeed instance.
        // It includes: NetworkSpeed structure +
        // size of zero-terminated "name" and "display" strings saved in
        // resp_data.
        *netspeed = malloc(sizeof(NetworkSpeed) + 1 +
                           resp.resp_data_size - sizeof(UICmdGetNetSpeedResp));
        ret = *netspeed;

        // Copy data obtained from the core to the returning NetworkSpeed
        // instance.
        ret->upload = resp_data->upload;
        ret->download = resp_data->download;
        ret->name = (char*)ret + sizeof(NetworkSpeed);
        strcpy((char*)ret->name, resp_data->name);
        ret->display = ret->name + strlen(ret->name) + 1;
        strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
    }
    if (resp_data != NULL) {
        free(resp_data);
    }
    return resp.result;
}

int
corecmd_get_netdelay(int index, NetworkLatency** netdelay)
{
    UICmdGetNetDelay req;
    UICmdRespHeader resp;
    UICmdGetNetDelayResp* resp_data = NULL;
    int status;

    // Initialize and send the query.
    req.index = index;
    status = _coreCmdProxy_send_command(AUICMD_GET_NETDELAY, &req, sizeof(req));
    if (status < 0) {
        return status;
    }

    // Obtain the response from the core.
    status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
    if (status < 0) {
        return status;
    }
    if (!resp.result) {
        NetworkLatency* ret;
        // Allocate memory for the returning NetworkLatency instance.
        // It includes: NetworkLatency structure +
        // size of zero-terminated "name" and "display" strings saved in
        // resp_data.
        *netdelay = malloc(sizeof(NetworkLatency) + 1 +
                           resp.resp_data_size - sizeof(UICmdGetNetDelayResp));
        ret = *netdelay;

        // Copy data obtained from the core to the returning NetworkLatency
        // instance.
        ret->min_ms = resp_data->min_ms;
        ret->max_ms = resp_data->max_ms;
        ret->name = (char*)ret + sizeof(NetworkLatency);
        strcpy((char*)ret->name, resp_data->name);
        ret->display = ret->name + strlen(ret->name) + 1;
        strcpy((char*)ret->display, resp_data->name + strlen(resp_data->name) + 1);
    }
    if (resp_data != NULL) {
        free(resp_data);
    }
    return resp.result;
}

int
corecmd_get_qemu_path(int type,
                      const char* filename,
                      char* path,
                      size_t path_buf_size)
{
    UICmdRespHeader resp;
    char* resp_data = NULL;
    int status;

    // Initialize and send the query.
    uint32_t cmd_data_size = sizeof(UICmdGetQemuPath) + strlen(filename) + 1;
    UICmdGetQemuPath* req = (UICmdGetQemuPath*)malloc(cmd_data_size);
    if (req == NULL) {
        APANIC("corecmd_get_qemu_path is unable to allocate %u bytes\n",
               cmd_data_size);
    }
    req->type = type;
    strcpy(req->filename, filename);
    status = _coreCmdProxy_send_command(AUICMD_GET_QEMU_PATH, req,
                                        cmd_data_size);
    if (status < 0) {
        return status;
    }

    // Obtain the response from the core.
    status = _coreCmdProxy_get_response(&resp, (void**)&resp_data);
    if (status < 0) {
        return status;
    }
    if (!resp.result && resp_data != NULL) {
        strncpy(path, resp_data, path_buf_size);
        path[path_buf_size - 1] = '\0';
    }
    if (resp_data != NULL) {
        free(resp_data);
    }
    return resp.result;
}

int
corecmd_get_hw_lcd_density(void)
{
    UICmdRespHeader resp;
    void* tmp = NULL;
    int status;

    status = _coreCmdProxy_send_command(AUICMD_GET_LCD_DENSITY, NULL, 0);
    if (status < 0) {
        return status;
    }
    status = _coreCmdProxy_get_response(&resp, &tmp);
    if (status < 0) {
        return status;
    }
    return resp.result;
}

int
coreCmdProxy_create(SockAddress* console_socket)
{
    char* handshake = NULL;

    // Connect to the ui-core-control service.
    _coreCmdProxy.core_connection =
        core_connection_create_and_switch(console_socket, "ui-core-control",
                                          &handshake);
    if (_coreCmdProxy.core_connection == NULL) {
        derror("Unable to connect to the ui-core-control service: %s\n",
               errno_str);
        return -1;
    }

    // Initialze command writer and response reader.
    _coreCmdProxy.sock = core_connection_get_socket(_coreCmdProxy.core_connection);
    _coreCmdProxy.sync_writer = syncsocket_init(_coreCmdProxy.sock);
    if (_coreCmdProxy.sync_writer == NULL) {
        derror("Unable to initialize CoreCmdProxy writer: %s\n", errno_str);
        coreCmdProxy_destroy();
        return -1;
    }
    _coreCmdProxy.sync_reader = syncsocket_init(_coreCmdProxy.sock);
    if (_coreCmdProxy.sync_reader == NULL) {
        derror("Unable to initialize CoreCmdProxy reader: %s\n", errno_str);
        coreCmdProxy_destroy();
        return -1;
    }


    fprintf(stdout, "ui-core-control is now connected to the core at %s.",
            sock_address_to_string(console_socket));
    if (handshake != NULL) {
        if (handshake[0] != '\0') {
            fprintf(stdout, " Handshake: %s", handshake);
        }
        free(handshake);
    }
    fprintf(stdout, "\n");

    return 0;
}

/* Destroys CoreCmdProxy instance. */
void
coreCmdProxy_destroy(void)
{
    if (_coreCmdProxy.sync_writer != NULL) {
        syncsocket_close(_coreCmdProxy.sync_writer);
        syncsocket_free(_coreCmdProxy.sync_writer);
        _coreCmdProxy.sync_writer = NULL;
    }
    if (_coreCmdProxy.sync_reader != NULL) {
        syncsocket_close(_coreCmdProxy.sync_reader);
        syncsocket_free(_coreCmdProxy.sync_reader);
        _coreCmdProxy.sync_reader = NULL;
    }
    if (_coreCmdProxy.core_connection != NULL) {
        core_connection_close(_coreCmdProxy.core_connection);
        core_connection_free(_coreCmdProxy.core_connection);
        _coreCmdProxy.core_connection = NULL;
    }
}
