/*
 * Ibis - IRCv3 Library
 * Copyright (C) 2022-2024 Ibis Developers
 *
 * Ibis is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This library 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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

#if !defined(IBIS_GLOBAL_HEADER_INSIDE) && !defined(IBIS_COMPILATION)
# error "only <ibis.h> may be included directly"
#endif

#ifndef IBIS_TAGS_H
#define IBIS_TAGS_H

#include <glib.h>
#include <glib-object.h>

#include "ibisversion.h"

/**
 * IBIS_TAGS_ERROR:
 *
 * A #GError domain for tags.
 *
 * Since: 0.1
 */
#define IBIS_TAGS_ERROR \
	(g_quark_from_static_string("ibis-tags")) \
	IBIS_AVAILABLE_MACRO_IN_0_1

G_BEGIN_DECLS

/**
 * IbisTags:
 *
 * An object for managing message tags.
 *
 * Since: 0.1
 */
#define IBIS_TYPE_TAGS (ibis_tags_get_type())

IBIS_AVAILABLE_IN_0_1
G_DECLARE_FINAL_TYPE(IbisTags, ibis_tags, IBIS, TAGS, GObject)

/**
 * ibis_tags_add:
 * @key: the key of the new tag
 * @value: the unescaped value to add
 *
 * Adds the new @key and @value to @tags.
 *
 * If @key already existed, it will be replaced.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
void ibis_tags_add(IbisTags *tags, const char *key, const char *value);

/**
 * ibis_tags_clear:
 *
 * Removes all tags from @tags.
 *
 * Since: 0.10
 */
IBIS_AVAILABLE_IN_0_10
void ibis_tags_clear(IbisTags *tags);

/**
 * ibis_tags_contains:
 * @tags1: the first instance
 * @tags2: the second instance
 *
 * Checks if all of the keys and values in @tags2 exist in @tags1.
 *
 * Returns: true if all keys and values from @tags2 can be found in @tags1;
 *          false otherwise.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
gboolean ibis_tags_contains(IbisTags *tags1, IbisTags *tags2);

/**
 * ibis_tags_equal:
 * @tags1: the first instance
 * @tags2: the second instance
 *
 * Checks if both @tags1 and @tags2 contain the exact same keys and values.
 *
 * Return: true if the same keys and values are found in both tags; false
 *         otherwise.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
gboolean ibis_tags_equal(IbisTags *tags1, IbisTags *tags2);

/**
 * ibis_tags_exists:
 * @key: the key to look for
 *
 * Checks whether or not @key exists in @tags.
 *
 * Returns: true if @key was found; false otherwise.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
gboolean ibis_tags_exists(IbisTags *tags, const char *key);

/**
 * ibis_tags_get_size:
 *
 * Gets the number of tags in @tags.
 *
 * Returns: The number of tags in @tags.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
guint ibis_tags_get_size(IbisTags *tags);

/**
 * ibis_tags_lookup:
 * @key: the key to lookup
 *
 * Looks up @key in @tags and returns the value.
 *
 * Returns: (nullable): The value of @key if found.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
const char *ibis_tags_lookup(IbisTags *tags, const char *key);

/**
 * ibis_tags_new:
 *
 * Creates a new tags instance.
 *
 * Returns: (transfer full): The new instance.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
IbisTags *ibis_tags_new(void);

/**
 * ibis_tags_parse:
 * @tags_string: the string to parse
 * @error: (nullable): a return address for a #GError
 *
 * Parses @tags_string and returns the result.
 *
 * If an error was encountered, %NULL will be returned and @error will be set.
 *
 * Returns: (transfer full) (nullable): The new tags object.
 *
 * Since: 0.1
 */
IBIS_DEPRECATED_FOR(ibis_tags_parse_string)
IbisTags *ibis_tags_parse(const char *tags_string, GError **error);

/**
 * ibis_tags_parse_string:
 * @tags_string: the string to parse
 * @error: (nullable): a return address for a #GError
 *
 * Parses @tags_string and updates @tags with the results.
 *
 * This calls [method@Tags.clear] before adding any new tags.
 *
 * If an error was encountered, @error will be set.
 *
 * Since: 0.10
 */
IBIS_AVAILABLE_IN_0_10
void ibis_tags_parse_string(IbisTags *tags, const char *tags_string, GError **error);

/**
 * ibis_tags_remove:
 * @key: the key to remove
 *
 * Removes @key from @tags.
 *
 * Returns: true if @key was found and removed; false otherwise.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
gboolean ibis_tags_remove(IbisTags *tags, const char *key);

/**
 * ibis_tags_serialize:
 *
 * Serializes @tags to a string.
 *
 * Returns: (transfer full): The serialized string.
 *
 * Since: 0.1
 */
IBIS_AVAILABLE_IN_0_1
char *ibis_tags_serialize(IbisTags *tags);

G_END_DECLS

#endif /* IBIS_TAGS_H */
