/*
 * Virtual hardware watchdog.
 *
 * Copyright (C) 2009 Red Hat Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * By Richard W.M. Jones (rjones@redhat.com).
 */

#include "qemu/osdep.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/queue.h"
#include "qapi/qmp/types.h"
#include "sysemu/sysemu.h"
#include "sysemu/watchdog.h"
#include "qapi-event.h"
#include "hw/nmi.h"
#include "qemu/help_option.h"
#include "qmp-commands.h"

static WatchdogAction watchdog_action = WATCHDOG_ACTION_RESET;
static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;

void watchdog_add_model(WatchdogTimerModel *model)
{
    QLIST_INSERT_HEAD(&watchdog_list, model, entry);
}

/* Returns:
 *   0 = continue
 *   1 = exit program with error
 *   2 = exit program without error
 */
int select_watchdog(const char *p)
{
    WatchdogTimerModel *model;
    QemuOpts *opts;

    /* -watchdog ? lists available devices and exits cleanly. */
    if (is_help_option(p)) {
        QLIST_FOREACH(model, &watchdog_list, entry) {
            fprintf(stderr, "\t%s\t%s\n",
                     model->wdt_name, model->wdt_description);
        }
        return 2;
    }

    QLIST_FOREACH(model, &watchdog_list, entry) {
        if (strcasecmp(model->wdt_name, p) == 0) {
            /* add the device */
            opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
                                    &error_abort);
            qemu_opt_set(opts, "driver", p, &error_abort);
            return 0;
        }
    }

    fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");
    QLIST_FOREACH(model, &watchdog_list, entry) {
        fprintf(stderr, "\t%s\t%s\n",
                 model->wdt_name, model->wdt_description);
    }
    return 1;
}

int select_watchdog_action(const char *p)
{
    int action;
    char *qapi_value;

    qapi_value = g_ascii_strdown(p, -1);
    action = qapi_enum_parse(&WatchdogAction_lookup, qapi_value, -1, NULL);
    g_free(qapi_value);
    if (action < 0)
        return -1;
    qmp_watchdog_set_action(action, &error_abort);
    return 0;
}

WatchdogAction get_watchdog_action(void)
{
    return watchdog_action;
}

/* This actually performs the "action" once a watchdog has expired,
 * ie. reboot, shutdown, exit, etc.
 */
void watchdog_perform_action(void)
{
    switch (watchdog_action) {
    case WATCHDOG_ACTION_RESET:     /* same as 'system_reset' in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_RESET, &error_abort);
        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
        break;

    case WATCHDOG_ACTION_SHUTDOWN:  /* same as 'system_powerdown' in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_SHUTDOWN, &error_abort);
        qemu_system_powerdown_request();
        break;

    case WATCHDOG_ACTION_POWEROFF:  /* same as 'quit' command in monitor */
        qapi_event_send_watchdog(WATCHDOG_ACTION_POWEROFF, &error_abort);
        exit(0);

    case WATCHDOG_ACTION_PAUSE:     /* same as 'stop' command in monitor */
        /* In a timer callback, when vm_stop calls qemu_clock_enable
         * you would get a deadlock.  Bypass the problem.
         */
        qemu_system_vmstop_request_prepare();
        qapi_event_send_watchdog(WATCHDOG_ACTION_PAUSE, &error_abort);
        qemu_system_vmstop_request(RUN_STATE_WATCHDOG);
        break;

    case WATCHDOG_ACTION_DEBUG:
        qapi_event_send_watchdog(WATCHDOG_ACTION_DEBUG, &error_abort);
        fprintf(stderr, "watchdog: timer fired\n");
        break;

    case WATCHDOG_ACTION_NONE:
        qapi_event_send_watchdog(WATCHDOG_ACTION_NONE, &error_abort);
        break;

    case WATCHDOG_ACTION_INJECT_NMI:
        qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI,
                                 &error_abort);
        nmi_monitor_handle(0, NULL);
        break;

    default:
        assert(0);
    }
}

void qmp_watchdog_set_action(WatchdogAction action, Error **errp)
{
    watchdog_action = action;
}
