/*
 * replay-char.c
 *
 * Copyright (c) 2010-2016 Institute for System Programming
 *                         of the Russian Academy of Sciences.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
#include "sysemu/sysemu.h"
#include "sysemu/char.h"

/* Char drivers that generate qemu_chr_be_write events
   that should be saved into the log. */
static Chardev **char_drivers;
static int drivers_count;

/* Char event attributes. */
typedef struct CharEvent {
    int id;
    uint8_t *buf;
    size_t len;
} CharEvent;

static int find_char_driver(Chardev *chr)
{
    int i = 0;
    for ( ; i < drivers_count ; ++i) {
        if (char_drivers[i] == chr) {
            return i;
        }
    }
    return -1;
}

void replay_register_char_driver(Chardev *chr)
{
    if (replay_mode == REPLAY_MODE_NONE) {
        return;
    }
    char_drivers = g_realloc(char_drivers,
                             sizeof(*char_drivers) * (drivers_count + 1));
    char_drivers[drivers_count++] = chr;
}

void replay_chr_be_write(Chardev *s, uint8_t *buf, int len)
{
    CharEvent *event = g_malloc0(sizeof(CharEvent));

    event->id = find_char_driver(s);
    if (event->id < 0) {
        fprintf(stderr, "Replay: cannot find char driver\n");
        exit(1);
    }
    event->buf = g_malloc(len);
    memcpy(event->buf, buf, len);
    event->len = len;

    replay_add_event(REPLAY_ASYNC_EVENT_CHAR_READ, event, NULL, 0);
}

void replay_event_char_read_run(void *opaque)
{
    CharEvent *event = (CharEvent *)opaque;

    qemu_chr_be_write_impl(char_drivers[event->id], event->buf,
                           (int)event->len);

    g_free(event->buf);
    g_free(event);
}

void replay_event_char_read_save(void *opaque)
{
    CharEvent *event = (CharEvent *)opaque;

    replay_put_byte(event->id);
    replay_put_array(event->buf, event->len);
}

void *replay_event_char_read_load(void)
{
    CharEvent *event = g_malloc0(sizeof(CharEvent));

    event->id = replay_get_byte();
    replay_get_array_alloc(&event->buf, &event->len);

    return event;
}

void replay_char_write_event_save(int res, int offset)
{
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_WRITE);
    replay_put_dword(res);
    replay_put_dword(offset);
    replay_mutex_unlock();
}

void replay_char_write_event_load(int *res, int *offset)
{
    replay_account_executed_instructions();
    replay_mutex_lock();
    if (replay_next_event_is(EVENT_CHAR_WRITE)) {
        *res = replay_get_dword();
        *offset = replay_get_dword();
        replay_finish_event();
        replay_mutex_unlock();
    } else {
        replay_mutex_unlock();
        error_report("Missing character write event in the replay log");
        exit(1);
    }
}

int replay_char_read_all_load(uint8_t *buf)
{
    replay_mutex_lock();
    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
        size_t size;
        int res;
        replay_get_array(buf, &size);
        replay_finish_event();
        replay_mutex_unlock();
        res = (int)size;
        assert(res >= 0);
        return res;
    } else if (replay_next_event_is(EVENT_CHAR_READ_ALL_ERROR)) {
        int res = replay_get_dword();
        replay_finish_event();
        replay_mutex_unlock();
        return res;
    } else {
        replay_mutex_unlock();
        error_report("Missing character read all event in the replay log");
        exit(1);
    }
}

void replay_char_read_all_save_error(int res)
{
    assert(res < 0);
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_READ_ALL_ERROR);
    replay_put_dword(res);
    replay_mutex_unlock();
}

void replay_char_read_all_save_buf(uint8_t *buf, int offset)
{
    replay_save_instructions();
    replay_mutex_lock();
    replay_put_event(EVENT_CHAR_READ_ALL);
    replay_put_array(buf, offset);
    replay_mutex_unlock();
}
