/*
 * 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 "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)
{
    g_assert(replay_mutex_locked());

    replay_save_instructions();
    replay_put_event(EVENT_CHAR_WRITE);
    replay_put_dword(res);
    replay_put_dword(offset);
}

void replay_char_write_event_load(int *res, int *offset)
{
    g_assert(replay_mutex_locked());

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

int replay_char_read_all_load(uint8_t *buf)
{
    g_assert(replay_mutex_locked());

    if (replay_next_event_is(EVENT_CHAR_READ_ALL)) {
        size_t size;
        int res;
        replay_get_array(buf, &size);
        replay_finish_event();
        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();
        return res;
    } else {
        error_report("Missing character read all event in the replay log");
        exit(1);
    }
}

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

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