/*
 * 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_del(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 nb_sns, i;
    AioContext *aio_context;

    *snapshot_icount = -1;

    bs = bdrv_all_find_vmstate_bs();
    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++) {
        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs) == 0) {
            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, 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", NULL) != 0) {
            /* Can't create the snapshot. Continue conventional debugging. */
        }
    }
}
