/*
 * replay-snapshot.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 "qapi/error.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
#include "sysemu/sysemu.h"
#include "monitor/monitor.h"
#include "qapi/qmp/qstring.h"
#include "qemu/error-report.h"
#include "migration/vmstate.h"
#include "migration/snapshot.h"

static int replay_pre_save(void *opaque)
{
    ReplayState *state = opaque;
    state->file_offset = ftell(replay_file);
    state->host_clock_last = qemu_clock_get_last(QEMU_CLOCK_HOST);

    return 0;
}

static int replay_post_load(void *opaque, int version_id)
{
    ReplayState *state = opaque;
    if (replay_mode == REPLAY_MODE_PLAY) {
        fseek(replay_file, state->file_offset, SEEK_SET);
        qemu_clock_set_last(QEMU_CLOCK_HOST, state->host_clock_last);
        /* If this was a vmstate, saved in recording mode,
           we need to initialize replay data fields. */
        replay_fetch_data_kind();
    } else if (replay_mode == REPLAY_MODE_RECORD) {
        /* This is only useful for loading the initial state.
           Therefore reset all the counters. */
        state->instructions_count = 0;
        state->block_request_id = 0;
    }

    return 0;
}

static const VMStateDescription vmstate_replay = {
    .name = "replay",
    .version_id = 1,
    .minimum_version_id = 1,
    .pre_save = replay_pre_save,
    .post_load = replay_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_INT64_ARRAY(cached_clock, ReplayState, REPLAY_CLOCK_COUNT),
        VMSTATE_UINT64(current_step, ReplayState),
        VMSTATE_INT32(instructions_count, ReplayState),
        VMSTATE_UINT32(data_kind, ReplayState),
        VMSTATE_UINT32(has_unread_data, ReplayState),
        VMSTATE_UINT64(file_offset, ReplayState),
        VMSTATE_UINT64(block_request_id, ReplayState),
        VMSTATE_UINT64(host_clock_last, ReplayState),
        VMSTATE_INT32(read_event_kind, ReplayState),
        VMSTATE_UINT64(read_event_id, ReplayState),
        VMSTATE_INT32(read_event_checkpoint, ReplayState),
        VMSTATE_END_OF_LIST()
    },
};

void replay_vmstate_register(void)
{
    vmstate_register(NULL, 0, &vmstate_replay, &replay_state);
}

void replay_vmstate_init(void)
{
    Error *err = NULL;

    if (replay_snapshot) {
        if (replay_mode == REPLAY_MODE_RECORD) {
            if (save_snapshot(replay_snapshot, &err) != 0) {
                error_report_err(err);
                error_report("Could not create snapshot for icount record");
                exit(1);
            }
        } else if (replay_mode == REPLAY_MODE_PLAY) {
            if (load_snapshot(replay_snapshot, &err) != 0) {
                error_report_err(err);
                error_report("Could not load snapshot for icount replay");
                exit(1);
            }
        }
    }
}

bool replay_can_snapshot(void)
{
    return replay_mode == REPLAY_MODE_NONE
        || !replay_has_events();
}
