/*
 * QEMU Error Objects
 *
 * Copyright IBM, Corp. 2011
 * Copyright (C) 2011-2015 Red Hat, Inc.
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *  Markus Armbruster <armbru@redhat.com>,
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.  See
 * the COPYING.LIB file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"

struct Error
{
    char *msg;
    ErrorClass err_class;
    const char *src, *func;
    int line;
    GString *hint;
};

Error *error_abort;
Error *error_fatal;
Error *error_warn;

static void error_handle(Error **errp, Error *err)
{
    if (errp == &error_abort) {
        fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
                err->func, err->src, err->line);
        error_report("%s", error_get_pretty(err));
        if (err->hint) {
            error_printf("%s", err->hint->str);
        }
        abort();
    }
    if (errp == &error_fatal) {
        error_report_err(err);
        exit(1);
    }
    if (errp == &error_warn) {
        warn_report_err(err);
    } else if (errp && !*errp) {
        *errp = err;
    } else {
        error_free(err);
    }
}

G_GNUC_PRINTF(6, 0)
static void error_setv(Error **errp,
                       const char *src, int line, const char *func,
                       ErrorClass err_class, const char *fmt, va_list ap,
                       const char *suffix)
{
    Error *err;
    int saved_errno = errno;

    if (errp == NULL) {
        return;
    }
    assert(*errp == NULL);

    err = g_malloc0(sizeof(*err));
    err->msg = g_strdup_vprintf(fmt, ap);
    if (suffix) {
        char *msg = err->msg;
        err->msg = g_strdup_printf("%s: %s", msg, suffix);
        g_free(msg);
    }
    err->err_class = err_class;
    err->src = src;
    err->line = line;
    err->func = func;

    error_handle(errp, err);

    errno = saved_errno;
}

void error_set_internal(Error **errp,
                        const char *src, int line, const char *func,
                        ErrorClass err_class, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    error_setv(errp, src, line, func, err_class, fmt, ap, NULL);
    va_end(ap);
}

void error_setg_internal(Error **errp,
                         const char *src, int line, const char *func,
                         const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap, NULL);
    va_end(ap);
}

void error_setg_errno_internal(Error **errp,
                               const char *src, int line, const char *func,
                               int os_errno, const char *fmt, ...)
{
    va_list ap;
    int saved_errno = errno;

    va_start(ap, fmt);
    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
               os_errno != 0 ? strerror(os_errno) : NULL);
    va_end(ap);

    errno = saved_errno;
}

void error_setg_file_open_internal(Error **errp,
                                   const char *src, int line, const char *func,
                                   int os_errno, const char *filename)
{
    error_setg_errno_internal(errp, src, line, func, os_errno,
                              "Could not open '%s'", filename);
}

void error_vprepend(Error *const *errp, const char *fmt, va_list ap)
{
    GString *newmsg;

    if (!errp) {
        return;
    }

    newmsg = g_string_new(NULL);
    g_string_vprintf(newmsg, fmt, ap);
    g_string_append(newmsg, (*errp)->msg);
    g_free((*errp)->msg);
    (*errp)->msg = g_string_free(newmsg, 0);
}

void error_prepend(Error *const *errp, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    error_vprepend(errp, fmt, ap);
    va_end(ap);
}

void error_append_hint(Error *const *errp, const char *fmt, ...)
{
    va_list ap;
    int saved_errno = errno;
    Error *err;

    if (!errp) {
        return;
    }
    err = *errp;
    assert(err && errp != &error_abort && errp != &error_fatal);

    if (!err->hint) {
        err->hint = g_string_new(NULL);
    }
    va_start(ap, fmt);
    g_string_append_vprintf(err->hint, fmt, ap);
    va_end(ap);

    errno = saved_errno;
}

#ifdef _WIN32

void error_setg_win32_internal(Error **errp,
                               const char *src, int line, const char *func,
                               int win32_err, const char *fmt, ...)
{
    va_list ap;
    char *suffix = NULL;

    if (errp == NULL) {
        return;
    }

    if (win32_err != 0) {
        suffix = g_win32_error_message(win32_err);
    }

    va_start(ap, fmt);
    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR,
               fmt, ap, suffix);
    va_end(ap);

    g_free(suffix);
}

#endif

Error *error_copy(const Error *err)
{
    Error *err_new;

    err_new = g_malloc0(sizeof(*err));
    err_new->msg = g_strdup(err->msg);
    err_new->err_class = err->err_class;
    err_new->src = err->src;
    err_new->line = err->line;
    err_new->func = err->func;
    if (err->hint) {
        err_new->hint = g_string_new(err->hint->str);
    }

    return err_new;
}

ErrorClass error_get_class(const Error *err)
{
    return err->err_class;
}

const char *error_get_pretty(const Error *err)
{
    return err->msg;
}

void error_report_err(Error *err)
{
    error_report("%s", error_get_pretty(err));
    if (err->hint) {
        error_printf("%s", err->hint->str);
    }
    error_free(err);
}

void warn_report_err(Error *err)
{
    warn_report("%s", error_get_pretty(err));
    if (err->hint) {
        error_printf("%s", err->hint->str);
    }
    error_free(err);
}

bool warn_report_err_once_cond(bool *printed, Error *err)
{
    if (*printed) {
        error_free(err);
        return false;
    }
    *printed = true;
    warn_report_err(err);
    return true;
}

void error_reportf_err(Error *err, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    error_vprepend(&err, fmt, ap);
    va_end(ap);
    error_report_err(err);
}


void warn_reportf_err(Error *err, const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    error_vprepend(&err, fmt, ap);
    va_end(ap);
    warn_report_err(err);
}

void error_free(Error *err)
{
    if (err) {
        g_free(err->msg);
        if (err->hint) {
            g_string_free(err->hint, true);
        }
        g_free(err);
    }
}

void error_free_or_abort(Error **errp)
{
    assert(errp && *errp);
    error_free(*errp);
    *errp = NULL;
}

void error_propagate(Error **dst_errp, Error *local_err)
{
    if (!local_err) {
        return;
    }
    error_handle(dst_errp, local_err);
}

void error_propagate_prepend(Error **dst_errp, Error *err,
                             const char *fmt, ...)
{
    va_list ap;

    if (dst_errp && !*dst_errp) {
        va_start(ap, fmt);
        error_vprepend(&err, fmt, ap);
        va_end(ap);
    } /* else error is being ignored, don't bother with prepending */
    error_propagate(dst_errp, err);
}
