/* Copyright (C) 2018-2020  Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>

#include <igloo/config.h>
#include <igloo/error.h>

// grep '^#define igloo_ERROR_' include/igloo/error.h | sed 's/^#define igloo_ERROR_\([^ ]*\) \+\([^ ]\+ *-\?[0-9][^ ]\+\) */\1::/; s/::\/\* \+\([^:]\+\): \+\(.\+\) \+\*\//:\1:\2/; s/::\/\* \+\([^:]\+\) \+\*\//:\1:/' | while IFS=: read name message description; do uuid=$(uuid -v 5 c4ce7102-4f5b-4421-9fb7-adbb299e336e "$name"); p='    '; printf "$p{\n$p${p}ERROR_BASE(%s),\n$p$p.flags = 0,\n" "$name"; [ -n "$message" ] && printf "$p$p.message = \"%s\",\n" "$message"; [ -n "$description" ] && printf "$p$p.description = \"%s\",\n" "$description"; printf "$p$p.uuid = \"%s\",\n$p$p.akindof = NULL\n$p},\n" "$uuid"; done | sed '$s/,$//'

#define ERROR_BASE(x) .control = igloo_CONTROL_INIT3(igloo_CONTROL_VERSION_BUILD(0), sizeof(igloo_error_desc_t), igloo_CONTROL_TYPE__ERROR_DESC), \
                      .error = igloo_ERROR_ ## x, \
                      .name = # x
static const igloo_error_desc_t errors[] = {
    {
        ERROR_BASE(GENERIC),
        .flags = 0,
        .message = "Generic error",
        .description = "A generic error occurred.",
        .uuid = "4f4dfebc-0b86-51e7-8233-73ff1c4707cf",
        .akindof = NULL
    },
    {
        ERROR_BASE(NONE),
        .flags = 0,
        .message = "No error",
        .description = "The operation succeeded.",
        .uuid = "3f9fa7d9-3d35-5358-bfa4-0c708bc2d7c9",
        .akindof = NULL
    },
    {
        ERROR_BASE(NOENT),
        .flags = 0,
        .message = "No such file, directory, or object",
        .uuid = "0bd73191-c0a8-5a60-8986-590aad6f937c",
        .akindof = NULL
    },
    {
        ERROR_BASE(NOSYS),
        .flags = 0,
        .message = "Function not implemented",
        .uuid = "5a6344ec-1c3e-5fb4-99ae-12443f7a9179",
        .akindof = NULL
    },
    {
        ERROR_BASE(RANGE),
        .flags = 0,
        .message = "Result out of range",
        .uuid = "945b9377-4829-51cc-9f70-60f5333ec08b",
        .akindof = NULL
    },
    {
        ERROR_BASE(NOMEM),
        .flags = 0,
        .message = "Not enough space",
        .uuid = "3c236243-fb2e-5f63-a8ff-255a496ff998",
        .akindof = NULL
    },
    {
        ERROR_BASE(INVAL),
        .flags = 0,
        .message = "Invalid argument",
        .uuid = "1146a208-c6aa-59be-93c5-e8c431e48892",
        .akindof = NULL
    },
    {
        ERROR_BASE(FAULT),
        .flags = 0,
        .message = "Invalid address",
        .uuid = "92ef9c60-654f-550d-a256-dc80a85ba0a0",
        .akindof = NULL
    },
    {
        ERROR_BASE(LOOP),
        .flags = 0,
        .message = "Too many recursions",
        .uuid = "5a10d13d-987f-5caa-bfbd-b555d94afd7a",
        .akindof = NULL
    },
    {
        ERROR_BASE(TYPEMM),
        .flags = 0,
        .message = "Type mismatch",
        .description = "Object of different type required",
        .uuid = "b3546924-99b9-5382-8121-095432d5381e",
        .akindof = NULL
    },
    {
        ERROR_BASE(ILLSEQ),
        .flags = 0,
        .message = "Illegal byte sequence",
        .uuid = "b5e35670-1abf-53aa-9766-7904ad4951e6",
        .akindof = NULL
    },
    {
        ERROR_BASE(NSVERSION),
        .flags = 0,
        .message = "Not supported version",
        .uuid = "8e71a2e4-e00f-5ae0-bdb8-4ed2cd97c841",
        .akindof = NULL
    },
    {
        ERROR_BASE(GONE),
        .flags = 0,
        .message = "Resource gone",
        .uuid = "40894986-e34a-5597-81d9-5a172934ead0",
        .akindof = NULL
    },
    {
        ERROR_BASE(BADSTATE),
        .flags = 0,
        .message = "Object is in bad/wrong state",
        .uuid = "7eced33a-68e2-5dc3-afa3-237fb85c2302",
        .akindof = NULL
    }
};

const igloo_error_desc_t *      igloo_error_get_description(igloo_error_t error)
{
    size_t i;

    for (i = 0; i < (sizeof(errors)/sizeof(*errors)); i++) {
        if (errors[i].error == error)
            return &(errors[i]);
    }

    return NULL;
}

const igloo_error_desc_t *      igloo_error_getbyname(const char *name)
{
    size_t i;

    for (i = 0; i < (sizeof(errors)/sizeof(*errors)); i++) {
        if (strcmp(errors[i].name, name) == 0)
            return &(errors[i]);
    }

    return NULL;
}
