/*
 * Ibis - IRCv3 Library
 * Copyright (C) 2022-2024 Ibis Developers <devel@pidgin.im>
 *
 * 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_FEATURES_H
#define IBIS_FEATURES_H

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

#include "ibisversion.h"
#include "ibismessage.h"

G_BEGIN_DECLS

#define IBIS_TYPE_FEATURES (ibis_features_get_type())

/**
 * IbisFeatures:
 *
 * An object that keeps track of the features a server supports.
 *
 * Since: 0.3
 */

IBIS_AVAILABLE_IN_0_3
G_DECLARE_FINAL_TYPE(IbisFeatures, ibis_features, IBIS, FEATURES, GObject)

/**
 * ibis_features_clear:
 *
 * Clears all features from @features and sets the default values per
 * https://modern.ircdocs.horse/#rplisupport-parameters.
 *
 * Since: 0.4
 */
IBIS_AVAILABLE_IN_0_4
void ibis_features_clear(IbisFeatures *features);

/**
 * ibis_features_client_tag_denied:
 * @tag: the tag to query
 *
 * Query the CLIENTTAGDENY parameter from @features.
 *
 * See [const@FEATURE_CLIENTTAGDENY].
 *
 * Returns: true if @tag is a blocked client-only tag; false otherwise.
 *
 * Since: 0.6
 */
IBIS_AVAILABLE_IN_0_6
gboolean ibis_features_client_tag_denied(IbisFeatures *features, const char *tag);

/**
 * ibis_features_new:
 *
 * Create a new features object.
 *
 * Returns: (transfer full): The new features object.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
IbisFeatures *ibis_features_new(void);

/**
 * ibis_features_parse:
 * @message: the message to parse
 *
 * Parses an RPL_ISUPPORT message into a features object.
 *
 * Returns: true if parsing was successful; false otherwise.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
gboolean ibis_features_parse(IbisFeatures *features, IbisMessage *message);

/**
 * ibis_features_get_awaylen:
 *
 * Gets the AWAYLEN parameter from @features.
 *
 * See [const@FEATURE_AWAYLEN].
 *
 * Returns: The AWAYLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_awaylen(IbisFeatures *features);

/**
 * ibis_features_get_casemapping:
 *
 * Gets the CASEMAPPING parameter from @features.
 *
 * See [const@FEATURE_CASEMAPPING].
 *
 * Returns: (nullable): The CASEMAPPING if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_casemapping(IbisFeatures *features);

/**
 * ibis_features_get_chanlimit:
 *
 * Gets the CHANLIMIT parameter from @features.
 *
 * See [const@FEATURE_CHANLIMIT].
 *
 * Returns: (nullable): The CHANLIMIT if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_chanlimit(IbisFeatures *features);

/**
 * ibis_features_get_chanmodes:
 *
 * Gets the CHANMODES parameter from @features.
 *
 * See [const@FEATURE_CHANMODES].
 *
 * Returns: (nullable): The CHANMODES if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_chanmodes(IbisFeatures *features);

/**
 * ibis_features_get_chantypes:
 *
 * Gets the CHANTYPES parameter from @features.
 *
 * See [const@FEATURE_CHANTYPES].
 *
 * Returns: The CHANTYPES or the default value of '#' if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_chantypes(IbisFeatures *features);

/**
 * ibis_features_get_channellen:
 *
 * Gets the CHANNELLEN parameter from @features.
 *
 * See [const@FEATURE_CHANNELLEN].
 *
 * Returns: The CHANNELLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_channellen(IbisFeatures *features);

/**
 * ibis_features_get_elist:
 *
 * Gets the ELIST parameter from @features.
 *
 * See [const@FEATURE_ELIST].
 *
 * Returns: (nullable): The ELIST if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_elist(IbisFeatures *features);

/**
 * ibis_features_get_excepts:
 *
 * Gets the EXCEPTS parameter from @features.
 *
 * See [const@FEATURE_EXCEPTS].
 *
 * Returns: The EXCEPTS or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
char ibis_features_get_excepts(IbisFeatures *features);

/**
 * ibis_features_get_extban:
 *
 * Gets the EXTBAN parameter from @features.
 *
 * See [const@FEATURE_EXTBAN].
 *
 * Returns: (nullable): The EXTBAN if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_extban(IbisFeatures *features);

/**
 * ibis_features_get_hostlen:
 *
 * Gets the HOSTLEN parameter from @features.
 *
 * See [const@FEATURE_HOSTLEN].
 *
 * Returns: The HOSTLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_hostlen(IbisFeatures *features);

/**
 * ibis_features_get_invex:
 *
 * Gets the INVEX parameter from @features.
 *
 * See [const@FEATURE_INVEX].
 *
 * Returns: The INVEX or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
char ibis_features_get_invex(IbisFeatures *features);

/**
 * ibis_features_get_kicklen:
 *
 * Gets the KICKLEN parameter from @features.
 *
 * See [const@FEATURE_KICKLEN].
 *
 * Returns: The KICKLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_kicklen(IbisFeatures *features);

/**
 * ibis_features_get_maxlist:
 *
 * Gets the MAXLIST parameter from @features.
 *
 * See [const@FEATURE_MAXLIST].
 *
 * Returns: (nullable): The MAXLIST if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_maxlist(IbisFeatures *features);

/**
 * ibis_features_get_maxtargets:
 *
 * Gets the MAXTARGETS parameter from @features.
 *
 * See [const@FEATURE_MAXTARGETS].
 *
 * Returns: The MAXTARGETS or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_maxtargets(IbisFeatures *features);

/**
 * ibis_features_get_modes:
 *
 * Gets the MODES parameter from @features.
 *
 * See [const@FEATURE_MODES].
 *
 * Returns: The MODES or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_modes(IbisFeatures *features);

/**
 * ibis_features_get_network:
 *
 * Gets the NETWORK parameter from @features.
 *
 * See [const@FEATURE_NETWORK].
 *
 * Returns: (nullable): The NETWORK if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_network(IbisFeatures *features);

/**
 * ibis_features_get_nicklen:
 *
 * Gets the NICKLEN parameter from @features.
 *
 * See [const@FEATURE_NICKLEN].
 *
 * Returns: The NICKLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_nicklen(IbisFeatures *features);

/**
 * ibis_features_get_prefix:
 *
 * Gets the PREFIX parameter from @features.
 *
 * See [const@FEATURE_PREFIX].
 *
 * Returns: The PREFIX or the default value of '(ov)@+' if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_prefix(IbisFeatures *features);

/**
 * ibis_features_get_prefix_modes:
 *
 * Gets the modes portion of the prefix feature.
 *
 * This is a synthetic feature that isn't defined by any specification.
 *
 * Returns: The modes portion of [const@FEATURE_PREFIX].
 *
 * Since: 0.8
 */
IBIS_AVAILABLE_IN_0_8
const char *ibis_features_get_prefix_modes(IbisFeatures *features);

/**
 * ibis_features_get_prefix_prefixes:
 *
 * Gets the prefixes portion of the prefix feature.
 *
 * This is a synthetic feature that isn't defined by any specification.
 *
 * Returns: The prefixes portion of [const@FEATURE_PREFIX].
 *
 * Since: 0.8
 */
IBIS_AVAILABLE_IN_0_8
const char *ibis_features_get_prefix_prefixes(IbisFeatures *features);

/**
 * ibis_features_get_safelist:
 *
 * Gets the SAFELIST parameter from @features.
 *
 * See [const@FEATURE_SAFELIST].
 *
 * Returns: true if SAFELIST parameter is advertised; false otherwise.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
gboolean ibis_features_get_safelist(IbisFeatures *features);

/**
 * ibis_features_get_silence:
 *
 * Gets the SILENCE parameter from @features.
 *
 * See [const@FEATURE_SILENCE].
 *
 * Returns: The SILENCE or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_silence(IbisFeatures *features);

/**
 * ibis_features_get_statusmsg:
 *
 * Gets the STATUSMSG parameter from @features.
 *
 * See [const@FEATURE_STATUSMSG].
 *
 * Returns: (nullable): The STATUSMSG if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_statusmsg(IbisFeatures *features);

/**
 * ibis_features_get_targmax:
 *
 * Gets the TARGMAX parameter from @features.
 *
 * See [const@FEATURE_TARGMAX].
 *
 * Returns: (nullable): The TARGMAX if it was set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_targmax(IbisFeatures *features);

/**
 * ibis_features_get_topiclen:
 *
 * Gets the TOPICLEN parameter from @features.
 *
 * See [const@FEATURE_TOPICLEN].
 *
 * Returns: The TOPICLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_topiclen(IbisFeatures *features);

/**
 * ibis_features_get_userlen:
 *
 * Gets the USERLEN parameter from @features.
 *
 * See [const@FEATURE_USERLEN].
 *
 * Returns: The USERLEN or 0 if not set.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_userlen(IbisFeatures *features);

/**
 * ibis_features_get_uint:
 * @parameter: a parameter name
 *
 * Gets the value of an unsigned integer parameter.
 *
 * Use this function to obtain the value of a parameter which is not covered by
 * any of the properties of the [class@Features] class but was parsed from an
 * [class@Message] using [method@Features.parse].
 *
 * Returns: The value of the parameter or 0 if it does not exist or is not
 *          an unsigned integer parameter.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
guint ibis_features_get_uint(IbisFeatures *features, const char *parameter);

/**
 * ibis_features_get_string:
 * @parameter: a parameter name
 *
 * Gets the value of a string parameter.
 *
 * Use this function to obtain the value of a parameter which is not covered by
 * any of the properties of the [class@Features] class but was parsed from an
 * [class@Message] using [method@Features.parse].
 *
 * Returns: (transfer none) (nullable): The value of the parameter if it exists
 *          and is a string parameter.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
const char *ibis_features_get_string(IbisFeatures *features, const char *parameter);

/**
 * ibis_features_get_boolean:
 * @parameter: a parameter name
 *
 * Gets the value of a boolean parameter.
 *
 * Use this function to obtain the value of a parameter which is not covered by
 * any of the properties of the [class@Features] class but was parsed from an
 * [class@Message] using [method@Features.parse].
 *
 * A parameter is considered boolean if it was advertised by the server without
 * specifying a value.
 *
 * Returns: true if @parameter was set and is a boolean parameter; false otherwise.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
gboolean ibis_features_get_boolean(IbisFeatures *features, const char *parameter);

/**
 * ibis_features_get_char:
 * @parameter: a parameter name
 *
 * Gets the value of a single character parameter.
 *
 * Use this function to obtain the value of a parameter which is not covered by
 * any of the properties of the [class@Features] class but was parsed from an
 * [class@Message] using [method@Features.parse].
 *
 * Returns: The value of the parameter or 0 if it does not
 *          exist or is not a single character parameter.
 *
 * Since: 0.3
 */
IBIS_AVAILABLE_IN_0_3
char ibis_features_get_char(IbisFeatures *features, const char *parameter);

G_END_DECLS

#endif /* IBIS_FEATURES_H */
