/*
 * 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 "chardev/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();
}
