/* Copyright (C) 2009 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 "android/boot-properties.h"
#include "android/utils/debug.h"
#include "android/utils/system.h"
#include "android/hw-qemud.h"
#include "android/globals.h"

#include "hw/hw.h"

#define  D(...)  VERBOSE_PRINT(init,__VA_ARGS__)

/* define T_ACTIVE to 1 to debug transport communications */
#define  T_ACTIVE  0

#if T_ACTIVE
#define  T(...)  VERBOSE_PRINT(init,__VA_ARGS__)
#else
#define  T(...)   ((void)0)
#endif

/* this code supports the list of system properties that will
 * be set on boot in the emulated system.
 */

typedef struct BootProperty {
    struct BootProperty*  next;
    char*                 property;
    int                   length;
} BootProperty;

static BootProperty*
boot_property_alloc( const char*  name,  int  namelen,
                     const char*  value, int  valuelen )
{
    int            length = namelen + 1 + valuelen;
    BootProperty*  prop = android_alloc( sizeof(*prop) + length + 1 );
    char*          p;

    prop->next     = NULL;
    prop->property = p = (char*)(prop + 1);
    prop->length   = length;

    memcpy( p, name, namelen );
    p += namelen;
    *p++ = '=';
    memcpy( p, value, valuelen );
    p += valuelen;
    *p = '\0';

    return prop;
}

static BootProperty*   _boot_properties = NULL;
/* address to store pointer to next new list element */
static BootProperty**  _boot_properties_tail = &_boot_properties;
static int             _inited;

/* Clears all existing boot properties
 */
static void
boot_property_clear_all()
{
    /* free all elements of the linked list */
    BootProperty *p = _boot_properties;
    BootProperty *next = NULL;
    while (p) {
        next = p->next;
        AFREE(p);
        p = next;
    }

    /* reset list administration to initial state */
    _boot_properties = NULL;
    _boot_properties_tail = &_boot_properties;
}

/* Appends a new boot property to the end of the internal list.
 */
int
boot_property_add2( const char*  name, int  namelen,
                    const char*  value, int  valuelen )
{
    BootProperty*  prop;

    /* check the lengths
     */
    if (namelen > PROPERTY_MAX_NAME)
        return -1;

    if (valuelen > PROPERTY_MAX_VALUE)
        return -2;

    /* check that there are not invalid characters in the
     * property name
     */
    const char*  reject = " =$*?'\"";
    int          nn;

    for (nn = 0; nn < namelen; nn++) {
        if (strchr(reject, name[nn]) != NULL)
            return -3;
    }

    /* init service if needed */
    if (!_inited) {
        boot_property_init_service();
        _inited = 1;
    }

    D("Adding boot property: '%.*s' = '%.*s'",
      namelen, name, valuelen, value);

    /* add to the end of the internal list */
    prop = boot_property_alloc(name, namelen, value, valuelen);

    *_boot_properties_tail = prop;
    _boot_properties_tail  = &prop->next;

    return 0;
}

/* Prints the warning string corresponding to the error code returned by
 * boot_propery_add2().
 */
static void
boot_property_raise_warning( int ret, const char*  name, int  namelen,
                             const char*  value, int  valuelen )
{
    switch (ret) {
    case -1:
        dwarning("boot property name too long: '%.*s'",
                    namelen, name);
        break;
    case -2:
        dwarning("boot property value too long: '%.*s'",
                    valuelen, value);
        break;
    case -3:
        dwarning("boot property name contains invalid chars: %.*s",
                    namelen, name);
        break;
    }
}

int
boot_property_add( const char*  name, const char*  value )
{
    int  namelen = strlen(name);
    int  valuelen = strlen(value);

    return boot_property_add2(name, namelen, value, valuelen);
}

/* Saves a single BootProperty to file.
 */
static int
boot_property_save_property( QEMUFile  *f, BootProperty  *p )
{
    /* split in key and value, so we can re-use boot_property_add (and its
     * sanity checks) when loading
     */

    char *split = strchr(p->property, '=');
    if (split == NULL) {
        D("%s: save failed: illegal key/value pair \"%s\" (missing '=')\n",
          __FUNCTION__, p->property);
        qemu_file_set_error(f, -EINVAL);
        return -1;
    }

    *split = '\0';  /* p->property is now "<key>\0<value>\0" */

    uint32_t key_buf_len = (split - p->property) + 1; // +1: '\0' terminator
    qemu_put_be32(f, key_buf_len);
    qemu_put_buffer(f, (uint8_t*) p->property, key_buf_len);

    uint32_t value_buf_len = p->length - key_buf_len + 1; // +1: '\0' terminator
    qemu_put_be32(f, value_buf_len);
    qemu_put_buffer(f, (uint8_t*) split + 1, value_buf_len);

    *split = '=';  /* restore property to "<key>=<value>\0" */

    return 0;
}

/* Loads a single boot property from a snapshot file
 */
static int
boot_property_load_property( QEMUFile  *f )
{
    int ret;

    /* load key */
    uint32_t key_buf_len = qemu_get_be32(f);
    char* key = android_alloc(key_buf_len);
    if ((ret = qemu_get_buffer(f, (uint8_t*)key, key_buf_len) != key_buf_len)) {
        D("%s: key load failed: expected %d bytes, got %d\n",
          __FUNCTION__, key_buf_len, ret);
        goto fail_key;
    }

    /* load value */
    uint32_t value_buf_len = qemu_get_be32(f);
    char* value = android_alloc(value_buf_len);
    if ((ret = qemu_get_buffer(f, (uint8_t*)value, value_buf_len) != value_buf_len)) {
        D("%s: value load failed: expected %d bytes, got %d\n",
          __FUNCTION__, value_buf_len, ret);
        goto fail_value;
    }

    /* add the property */
    ret = boot_property_add2(key, key_buf_len - 1, value, value_buf_len - 1);
    if (ret < 0) {
        D("%s: load failed: cannot add boot property (details follow)\n",
          __FUNCTION__);
        boot_property_raise_warning(ret, key, key_buf_len - 1, value, value_buf_len - 1);
        goto fail_value;
    }

    return 0;

    /* in case of errors, clean up before return */
    fail_value:
        AFREE(value);
    fail_key:
        AFREE(key);
        return -EIO;
}

/* Saves the number of available boot properties to file
 */
static void
boot_property_save_count( QEMUFile*  f, BootProperty*  p )
{
    uint32_t property_count = 0;
    for (; p; p = p->next) {
        property_count++;
    }

    qemu_put_be32(f, property_count);
}

/* Saves all available boot properties to snapshot.
 */
static void
boot_property_save( QEMUFile*  f, QemudService*  service, void*  opaque )
{
    boot_property_save_count(f, _boot_properties);

    BootProperty *p = _boot_properties;
    for ( ; p; p = p->next) {
        if (boot_property_save_property(f, p)) {
            break;  /* abort on error */
        }
    }
}

/* Replaces the currently available boot properties by those stored
 * in a snapshot.
 */
static int
boot_property_load( QEMUFile*  f, QemudService*  service, void*  opaque )
{
    int ret;

    /* remove properties from old run */
    boot_property_clear_all();

    /* load properties from snapshot */
    uint32_t i, property_count = qemu_get_be32(f);
    for (i = 0; i < property_count; i++) {
        if ((ret = boot_property_load_property(f))) {
            return ret;
        }
    }

    return 0;
}

#define SERVICE_NAME  "boot-properties"

static void
boot_property_client_recv( void*         opaque,
                           uint8_t*      msg,
                           int           msglen,
                           QemudClient*  client )
{
    /* the 'list' command shall send all boot properties
     * to the client, then close the connection.
     */
    if (msglen == 4 && !memcmp(msg, "list", 4)) {
        BootProperty*  prop;
        for (prop = _boot_properties; prop != NULL; prop = prop->next) {
            qemud_client_send(client, (uint8_t*)prop->property, prop->length);
        }

        /* Send a NUL to signal the end of the list. */
        qemud_client_send(client, (uint8_t*)"", 1);

        return;
    }

    /* unknown command ? */
    D("%s: ignoring unknown command: %.*s", __FUNCTION__, msglen, msg);
}

static QemudClient*
boot_property_service_connect( void*          opaque,
                               QemudService*  serv,
                               int            channel,
                               const char*    client_param )
{
    QemudClient*  client;

    client = qemud_client_new( serv, channel, client_param, NULL,
                               boot_property_client_recv,
                               NULL, NULL, NULL );

    qemud_client_set_framing(client, 1);
    return client;
}


void
boot_property_init_service( void )
{
    if (!_inited) {
        QemudService*  serv = qemud_service_register( SERVICE_NAME,
                                                      1, NULL,
                                                      boot_property_service_connect,
                                                      boot_property_save,
                                                      boot_property_load);
        if (serv == NULL) {
            derror("could not register '%s' service", SERVICE_NAME);
            return;
        }
        D("registered '%s' qemud service", SERVICE_NAME);
    }
}



void
boot_property_parse_option( const char*  param )
{
    char* q = strchr(param,'=');
    const char* name;
    const char* value;
    int   namelen, valuelen, ret;

    if (q == NULL) {
        dwarning("boot property missing (=) separator: %s", param);
        return;
    }

    name    = param;
    namelen = q - param;

    value    = q+1;
    valuelen = strlen(name) - (namelen+1);

    ret = boot_property_add2(name, namelen, value, valuelen);
    if (ret < 0) {
        boot_property_raise_warning(ret, name, namelen, value, valuelen);
    }
}
