/*
 * SPDX-FileCopyrightText: 2003-2026 Sébastien Helleu <flashcode@flashtux.org>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#ifndef WEECHAT_INFOLIST_H
#define WEECHAT_INFOLIST_H

#include <time.h>

struct t_weechat_plugin;

/* List structures */

enum t_infolist_type
{
    INFOLIST_INTEGER = 0,
    INFOLIST_STRING,
    INFOLIST_POINTER,
    INFOLIST_BUFFER,
    INFOLIST_TIME,
    INFOLIST_LONG,
    INFOLIST_LONGLONG,
    /* number of infolist types */
    INFOLIST_NUM_TYPES,
};

struct t_infolist_var
{
    char *name;                        /* variable name                     */
    enum t_infolist_type type;         /* type: int, string, ...            */
    void *value;                       /* pointer to value                  */
    int size;                          /* for type buffer                   */
    struct t_infolist_var *prev_var;   /* link to previous variable         */
    struct t_infolist_var *next_var;   /* link to next variable             */
};

struct t_infolist_item
{
    struct t_infolist_var *vars;       /* item variables                    */
    struct t_infolist_var *last_var;   /* last variable                     */
    struct t_infolist_var *cursor_var; /* last variable found by name, used */
                                       /* as a search starting point        */
                                       /* (callers usually read fields in   */
                                       /* roughly the order they were added)*/
    char *fields;                      /* fields list (NULL if never asked) */
    struct t_infolist_item *prev_item; /* link to previous item             */
    struct t_infolist_item *next_item; /* link to next item                 */
};

struct t_infolist
{
    struct t_weechat_plugin *plugin;   /* plugin which created this infolist*/
                                       /* (NULL if created by WeeChat)      */
    struct t_infolist_item *items;     /* link to items                     */
    struct t_infolist_item *last_item; /* last variable                     */
    struct t_infolist_item *ptr_item;  /* pointer to current item           */
    struct t_infolist *prev_infolist;  /* link to previous list             */
    struct t_infolist *next_infolist;  /* link to next list                 */
};

/* List variables */

extern struct t_infolist *weechat_infolists;
extern struct t_infolist *last_weechat_infolist;
extern char infolist_type_char_string[];

/* List functions */

extern struct t_infolist *infolist_new (struct t_weechat_plugin *plugin);
extern int infolist_valid (struct t_infolist *infolist);
extern struct t_infolist_item *infolist_new_item (struct t_infolist *infolist);
extern struct t_infolist_var *infolist_new_var_integer (struct t_infolist_item *item,
                                                        const char *name,
                                                        int value);
extern struct t_infolist_var *infolist_new_var_string (struct t_infolist_item *item,
                                                       const char *name,
                                                       const char *value);
extern struct t_infolist_var *infolist_new_var_pointer (struct t_infolist_item *item,
                                                        const char *name,
                                                        void *pointer);
extern struct t_infolist_var *infolist_new_var_buffer (struct t_infolist_item *item,
                                                       const char *name,
                                                       void *pointer,
                                                       int size);
extern struct t_infolist_var *infolist_new_var_time (struct t_infolist_item *item,
                                                     const char *name,
                                                     time_t time);
extern struct t_infolist_var *infolist_new_var_long (struct t_infolist_item *item,
                                                     const char *name,
                                                     long value);
extern struct t_infolist_var *infolist_new_var_longlong (struct t_infolist_item *item,
                                                         const char *name,
                                                         long long value);
/*
 * INTERNAL USE ONLY (core-upgrade-file.c): unlike infolist_new_var_string()/
 * infolist_new_var_buffer()/infolist_new_var_integer()/infolist_new_var_time()
 * above, these four do NOT copy "name" (and, for the string/buffer variants,
 * "value"/"pointer" either); the infolist takes ownership of the pointer(s) and
 * the caller must never use or free them afterwards: on success they are freed
 * later by infolist_var_free(), and on error (NULL return) they are freed
 * immediately by the function itself.
 * Do not expose these via struct t_weechat_plugin / weechat-plugin.h: the
 * plugin API contract is that infolist_new_var_* copy the name/value, and
 * callers rely on that.
 */
extern struct t_infolist_var *infolist_new_var_integer_take_name_ownership (struct t_infolist_item *item,
                                                                            char *name,
                                                                            int value);
extern struct t_infolist_var *infolist_new_var_string_take_ownership (struct t_infolist_item *item,
                                                                      char *name,
                                                                      char *value);
extern struct t_infolist_var *infolist_new_var_buffer_take_ownership (struct t_infolist_item *item,
                                                                      char *name,
                                                                      void *pointer,
                                                                      int size);
extern struct t_infolist_var *infolist_new_var_time_take_name_ownership (struct t_infolist_item *item,
                                                                         char *name,
                                                                         time_t time);
extern struct t_infolist_var *infolist_new_var_long_take_name_ownership (struct t_infolist_item *item,
                                                                         char *name, long value);
extern struct t_infolist_var *infolist_new_var_longlong_take_name_ownership (struct t_infolist_item *item,
                                                                             char *name, long long value);
extern struct t_infolist_var *infolist_search_var (struct t_infolist *infolist,
                                                   const char *name);
extern struct t_infolist_item *infolist_next (struct t_infolist *infolist);
extern struct t_infolist_item *infolist_prev (struct t_infolist *infolist);
extern void infolist_reset_item_cursor (struct t_infolist *infolist);
extern const char *infolist_fields (struct t_infolist *infolist);
extern int infolist_integer (struct t_infolist *infolist, const char *var);
extern const char *infolist_string (struct t_infolist *infolist, const char *var);
extern void *infolist_pointer (struct t_infolist *infolist, const char *var);
extern void *infolist_buffer (struct t_infolist *infolist, const char *var, int *size);
extern time_t infolist_time (struct t_infolist *infolist, const char *var);
extern long infolist_long (struct t_infolist *infolist, const char *var);
extern long long infolist_longlong (struct t_infolist *infolist, const char *var);
extern void infolist_free (struct t_infolist *infolist);
extern void infolist_free_all_plugin (struct t_weechat_plugin *plugin);
extern void infolist_print_log (void);

#endif /* WEECHAT_INFOLIST_H */
