/*
 * 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->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;

    *snapshot_icount = -1;

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

    nb_sns = bdrv_snapshot_list(bs, &sn_tab);

    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. */
        }
    }
}
