/*
 * replay-debugging.c
 *
 * Copyright (c) 2010-2020 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 "sysemu/runstate.h"
#include "replay-internal.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
#include "qapi/qapi-commands-replay.h"
#include "qapi/qmp/qdict.h"
#include "qemu/timer.h"
#include "block/snapshot.h"
#include "migration/snapshot.h"

static bool replay_is_debugging;
static int64_t replay_last_breakpoint;
static int64_t replay_last_snapshot;

bool replay_running_debug(void)
{
    return replay_is_debugging;
}

void hmp_info_replay(Monitor *mon, const QDict *qdict)
{
    if (replay_mode == REPLAY_MODE_NONE) {
        monitor_printf(mon, "Record/replay is not active\n");
    } else {
        monitor_printf(mon,
            "%s execution '%s': instruction count = %"PRId64"\n",
            replay_mode == REPLAY_MODE_RECORD ? "Recording" : "Replaying",
            replay_get_filename(), replay_get_current_icount());
    }
}

ReplayInfo *qmp_query_replay(Error **errp)
{
    ReplayInfo *retval = g_new0(ReplayInfo, 1);

    retval->mode = replay_mode;
    if (replay_get_filename()) {
        retval->filename = g_strdup(replay_get_filename());
        retval->has_filename = true;
    }
    retval->icount = replay_get_current_icount();
    return retval;
}

static void replay_break(uint64_t icount, QEMUTimerCB callback, void *opaque)
{
    assert(replay_mode == REPLAY_MODE_PLAY);
    assert(replay_mutex_locked());
    assert(replay_break_icount >= replay_get_current_icount());
    assert(callback);

    replay_break_icount = icount;

    if (replay_break_timer) {
        timer_del(replay_break_timer);
    }
    replay_break_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
                                      callback, opaque);
}

static void replay_delete_break(void)
{
    assert(replay_mode == REPLAY_MODE_PLAY);
    assert(replay_mutex_locked());

    if (replay_break_timer) {
        timer_free(replay_break_timer);
        replay_break_timer = NULL;
    }
    replay_break_icount = -1ULL;
}

static void replay_stop_vm(void *opaque)
{
    vm_stop(RUN_STATE_PAUSED);
    replay_delete_break();
}

void qmp_replay_break(int64_t icount, Error **errp)
{
    if (replay_mode == REPLAY_MODE_PLAY) {
        if (icount >= replay_get_current_icount()) {
            replay_break(icount, replay_stop_vm, NULL);
        } else {
            error_setg(errp,
                "cannot set breakpoint at the instruction in the past");
        }
    } else {
        error_setg(errp, "setting the breakpoint is allowed only in play mode");
    }
}

void hmp_replay_break(Monitor *mon, const QDict *qdict)
{
    int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
    Error *err = NULL;

    qmp_replay_break(icount, &err);
    if (err) {
        error_report_err(err);
        return;
    }
}

void qmp_replay_delete_break(Error **errp)
{
    if (replay_mode == REPLAY_MODE_PLAY) {
        replay_delete_break();
    } else {
        error_setg(errp, "replay breakpoints are allowed only in play mode");
    }
}

void hmp_replay_delete_break(Monitor *mon, const QDict *qdict)
{
    Error *err = NULL;

    qmp_replay_delete_break(&err);
    if (err) {
        error_report_err(err);
        return;
    }
}

static char *replay_find_nearest_snapshot(int64_t icount,
                                          int64_t *snapshot_icount)
{
    BlockDriverState *bs;
    QEMUSnapshotInfo *sn_tab;
    QEMUSnapshotInfo *nearest = NULL;
    char *ret = NULL;
    int rv;
    int nb_sns, i;
    AioContext *aio_context;

    *snapshot_icount = -1;

    bs = bdrv_all_find_vmstate_bs(NULL, false, NULL, NULL);
    if (!bs) {
        goto fail;
    }
    aio_context = bdrv_get_aio_context(bs);

    aio_context_acquire(aio_context);
    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
    aio_context_release(aio_context);

    for (i = 0; i < nb_sns; i++) {
        rv = bdrv_all_has_snapshot(sn_tab[i].name, false, NULL, NULL);
        if (rv < 0)
            goto fail;
        if (rv == 1) {
            if (sn_tab[i].icount != -1ULL
                && sn_tab[i].icount <= icount
                && (!nearest || nearest->icount < sn_tab[i].icount)) {
                nearest = &sn_tab[i];
            }
        }
    }
    if (nearest) {
        ret = g_strdup(nearest->name);
        *snapshot_icount = nearest->icount;
    }
    g_free(sn_tab);

fail:
    return ret;
}

static void replay_seek(int64_t icount, QEMUTimerCB callback, Error **errp)
{
    char *snapshot = NULL;
    int64_t snapshot_icount;

    if (replay_mode != REPLAY_MODE_PLAY) {
        error_setg(errp, "replay must be enabled to seek");
        return;
    }

    snapshot = replay_find_nearest_snapshot(icount, &snapshot_icount);
    if (snapshot) {
        if (icount < replay_get_current_icount()
            || replay_get_current_icount() < snapshot_icount) {
            vm_stop(RUN_STATE_RESTORE_VM);
            load_snapshot(snapshot, NULL, false, NULL, errp);
        }
        g_free(snapshot);
    }
    if (replay_get_current_icount() <= icount) {
        replay_break(icount, callback, NULL);
        vm_start();
    } else {
        error_setg(errp, "cannot seek to the specified instruction count");
    }
}

void qmp_replay_seek(int64_t icount, Error **errp)
{
    replay_seek(icount, replay_stop_vm, errp);
}

void hmp_replay_seek(Monitor *mon, const QDict *qdict)
{
    int64_t icount = qdict_get_try_int(qdict, "icount", -1LL);
    Error *err = NULL;

    qmp_replay_seek(icount, &err);
    if (err) {
        error_report_err(err);
        return;
    }
}

static void replay_stop_vm_debug(void *opaque)
{
    replay_is_debugging = false;
    vm_stop(RUN_STATE_DEBUG);
    replay_delete_break();
}

bool replay_reverse_step(void)
{
    Error *err = NULL;

    assert(replay_mode == REPLAY_MODE_PLAY);

    if (replay_get_current_icount() != 0) {
        replay_seek(replay_get_current_icount() - 1,
                    replay_stop_vm_debug, &err);
        if (err) {
            error_free(err);
            return false;
        }
        replay_is_debugging = true;
        return true;
    }

    return false;
}

static void replay_continue_end(void)
{
    replay_is_debugging = false;
    vm_stop(RUN_STATE_DEBUG);
    replay_delete_break();
}

static void replay_continue_stop(void *opaque)
{
    Error *err = NULL;
    if (replay_last_breakpoint != -1LL) {
        replay_seek(replay_last_breakpoint, replay_stop_vm_debug, &err);
        if (err) {
            error_free(err);
            replay_continue_end();
        }
        return;
    }
    /*
     * No breakpoints since the last snapshot.
     * Find previous snapshot and try again.
     */
    if (replay_last_snapshot != 0) {
        replay_seek(replay_last_snapshot - 1, replay_continue_stop, &err);
        if (err) {
            error_free(err);
            replay_continue_end();
        }
        replay_last_snapshot = replay_get_current_icount();
    } else {
        /* Seek to the very first step */
        replay_seek(0, replay_stop_vm_debug, &err);
        if (err) {
            error_free(err);
            replay_continue_end();
        }
    }
}

bool replay_reverse_continue(void)
{
    Error *err = NULL;

    assert(replay_mode == REPLAY_MODE_PLAY);

    if (replay_get_current_icount() != 0) {
        replay_seek(replay_get_current_icount() - 1,
                    replay_continue_stop, &err);
        if (err) {
            error_free(err);
            return false;
        }
        replay_last_breakpoint = -1LL;
        replay_is_debugging = true;
        replay_last_snapshot = replay_get_current_icount();
        return true;
    }

    return false;
}

void replay_breakpoint(void)
{
    assert(replay_mode == REPLAY_MODE_PLAY);
    replay_last_breakpoint = replay_get_current_icount();
}

void replay_gdb_attached(void)
{
    /*
     * Create VM snapshot on temporary overlay to allow reverse
     * debugging even if snapshots were not enabled.
     */
    if (replay_mode == REPLAY_MODE_PLAY
        && !replay_snapshot) {
        if (!save_snapshot("start_debugging", true, NULL, false, NULL, NULL)) {
            /* Can't create the snapshot. Continue conventional debugging. */
        }
    }
}
