/* Copyright (C) 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.
 */

#ifndef _LIBIGLOO__FEATURE_H_
#define _LIBIGLOO__FEATURE_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h> /* for size_t */
#include <stdbool.h>

#include <igloo/types.h>

/* ---[ PRIVATE ]--- */
/*
 * Those declarations are defined here as they must be known to the compiler.
 * Nobody should ever try to access them directly.
 */
struct igloo_feature_tag {
    /* Control structure */
    igloo_control_t             control;

    /* Name of feature */
    const char *                feature_name;

    /* STILL UNUSED: Feature description */
    const char *                feature_description;
    const char *                feature_uuid;
    const void *                type_reserved_ptr_0;
    const void *                type_reserved_ptr_1;
    const void *                type_reserved_ptr_2;
    const void *                type_reserved_ptr_3;
};

#define igloo_FEATURE__CONTROL_VERSION   igloo_CONTROL_VERSION_BUILD(1)
#define igloo_FEATURE__DEFINE_TYPE(name, suffix, ...) \
static igloo_feature_t igloo_feature__featuredef__ ## name = \
{ \
    .control = igloo_CONTROL_INIT3(igloo_FEATURE__CONTROL_VERSION, sizeof(igloo_feature_t), igloo_CONTROL_TYPE__FEATURE), \
    .feature_name = # name suffix, \
    , ## __VA_ARGS__ \
}
/* ---[ END PRIVATE ]--- */

#define igloo_FEATURE_FORWARD(name)         extern igloo_feature_t * name
#define igloo_FEATURE_PUBLIC(name, ...)     igloo_FEATURE__DEFINE_TYPE(name, "", ## __VA_ARGS__); igloo_feature_t * name = &(igloo_feature__featuredef__ ## name)
#define igloo_FEATURE_PRIVATE(name, ...)    igloo_FEATURE__DEFINE_TYPE(name, " (private)", ## __VA_ARGS__); static igloo_feature_t * name = &(igloo_feature__featuredef__ ## name)

igloo_error_t   igloo_feature_get_name(igloo_feature_t *feature, const char **name) igloo_ATTR_F_WARN_UNUSED_RESULT;
bool            igloo_feature_equal(igloo_feature_t *a, igloo_feature_t *b) igloo_ATTR_F_WARN_UNUSED_RESULT;


#ifdef __cplusplus
}
#endif

#endif /* ! _LIBIGLOO__FEATURE_H_ */
