/*
  This file is part of TALER
  Copyright (C) 2014-2026 Taler Systems SA

  TALER is free software; you can redistribute it and/or modify it under the
  terms of the GNU Affero General Public License as published by the Free Software
  Foundation; either version 3, or (at your option) any later version.

  TALER 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 Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License along with
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
/**
 * @file include/taler/exchange/get-kyc-info-ACCESS_TOKEN.h
 * @brief C interface for GET /kyc-info/$ACCESS_TOKEN
 * @author Christian Grothoff
 */
#ifndef _TALER_EXCHANGE__GET_KYC_INFO_ACCESS_TOKEN_H
#define _TALER_EXCHANGE__GET_KYC_INFO_ACCESS_TOKEN_H

#include <taler/exchange/common.h>

/**
 * Information about a KYC requirement the client must satisfy.
 */
struct TALER_EXCHANGE_RequirementInformation
{
  /**
   * Which form should be run.  Special values are
   * "INFO" (only show information, no form) and
   * "LINK" (only link to "/kyc-start/$ID").
   */
  const char *form;

  /**
   * Description of the check.
   */
  const char *description;

  /**
   * Translations of @e description, if available.
   */
  const json_t *description_i18n;

  /**
   * ID of the requirement, NULL if @e form is "INFO".
   * Used to construct the "/kyc-upload/$ID" and "/kyc-start/$ID" endpoints.
   */
  const char *id;

};


/**
 * Information about a KYC check the client may satisfy voluntarily.
 */
struct TALER_EXCHANGE_VoluntaryCheckInformation
{
  /**
   * Name of the check.
   */
  const char *name;

  /**
   * Description of the check.
   */
  const char *description;

  /**
   * Translations of @e description, if available.
   */
  const json_t *description_i18n;

};


/**
 * Possible options we can set for the GET kyc-info request.
 */
enum TALER_EXCHANGE_GetKycInfoOption
{
  /**
   * End of list of options.
   */
  TALER_EXCHANGE_GET_KYC_INFO_OPTION_END = 0,

  /**
   * HTTP ETag value from a previous response, for conditional requests.
   * If the server's current ETag matches, it will respond with
   * #MHD_HTTP_NOT_MODIFIED instead of repeating the full response.
   * Combined with TIMEOUT to implement efficient long polling.
   */
  TALER_EXCHANGE_GET_KYC_INFO_OPTION_IF_NONE_MATCH,

  /**
   * How long to wait for a change relative to @e if_none_match,
   * enabling long polling.  Default is zero (no long polling).
   */
  TALER_EXCHANGE_GET_KYC_INFO_OPTION_TIMEOUT

};


/**
 * Value for an option for the GET kyc-info request.
 */
struct TALER_EXCHANGE_GetKycInfoOptionValue
{
  /**
   * Type of the option being set.
   */
  enum TALER_EXCHANGE_GetKycInfoOption option;

  /**
   * Specific option value.
   */
  union
  {
    /**
     * Value if @e option is TALER_EXCHANGE_GET_KYC_INFO_OPTION_IF_NONE_MATCH.
     * HTTP ETag from a previous response.  The string must remain valid
     * for the lifetime of the operation.
     */
    const char *if_none_match;

    /**
     * Value if @e option is TALER_EXCHANGE_GET_KYC_INFO_OPTION_TIMEOUT.
     */
    struct GNUNET_TIME_Relative timeout;

  } details;

};


/**
 * Handle for an operation to GET /kyc-info/$ACCESS_TOKEN.
 */
struct TALER_EXCHANGE_GetKycInfoHandle;


/**
 * Set up GET /kyc-info/$ACCESS_TOKEN operation.
 * Note that you must explicitly start the operation after
 * possibly setting options.
 *
 * @param ctx the context
 * @param url base URL of the exchange
 * @param token access token of the client
 * @return handle to operation
 */
struct TALER_EXCHANGE_GetKycInfoHandle *
TALER_EXCHANGE_get_kyc_info_create (
  struct GNUNET_CURL_Context *ctx,
  const char *url,
  const struct TALER_AccountAccessTokenP *token);


/**
 * Terminate the list of options.
 *
 * @return the terminating object of struct TALER_EXCHANGE_GetKycInfoOptionValue
 */
#define TALER_EXCHANGE_get_kyc_info_option_end_()                   \
        (const struct TALER_EXCHANGE_GetKycInfoOptionValue)         \
        {                                                            \
          .option = TALER_EXCHANGE_GET_KYC_INFO_OPTION_END          \
        }

/**
 * Set ETag for conditional request / long polling.
 *
 * @param e HTTP ETag string from a previous response
 * @return representation of the option as a struct TALER_EXCHANGE_GetKycInfoOptionValue
 */
#define TALER_EXCHANGE_get_kyc_info_option_if_none_match(e)                   \
        (const struct TALER_EXCHANGE_GetKycInfoOptionValue)                   \
        {                                                                      \
          .option = TALER_EXCHANGE_GET_KYC_INFO_OPTION_IF_NONE_MATCH,         \
          .details.if_none_match = (e)                                         \
        }

/**
 * Set long-polling timeout.
 *
 * @param t how long to wait for a change
 * @return representation of the option as a struct TALER_EXCHANGE_GetKycInfoOptionValue
 */
#define TALER_EXCHANGE_get_kyc_info_option_timeout(t)                   \
        (const struct TALER_EXCHANGE_GetKycInfoOptionValue)             \
        {                                                                \
          .option = TALER_EXCHANGE_GET_KYC_INFO_OPTION_TIMEOUT,         \
          .details.timeout = (t)                                         \
        }


/**
 * Set the requested options for the operation.
 *
 * If any option fails, other options may or may not be applied.
 *
 * @param gkih the request to set the options for
 * @param num_options length of the @a options array
 * @param options an array of options
 * @return #GNUNET_OK on success,
 *         #GNUNET_NO on failure,
 *         #GNUNET_SYSERR on internal error
 */
enum GNUNET_GenericReturnValue
TALER_EXCHANGE_get_kyc_info_set_options_ (
  struct TALER_EXCHANGE_GetKycInfoHandle *gkih,
  unsigned int num_options,
  const struct TALER_EXCHANGE_GetKycInfoOptionValue *options);


/**
 * Set the requested options for the operation.
 *
 * If any option fails, other options may or may not be applied.
 *
 * It should be used with helpers that create required options, for example:
 *
 * TALER_EXCHANGE_get_kyc_info_set_options (
 *   gkih,
 *   TALER_EXCHANGE_get_kyc_info_option_if_none_match (last_etag),
 *   TALER_EXCHANGE_get_kyc_info_option_timeout (timeout));
 *
 * @param gkih the request to set the options for
 * @param ... the list of options, each created by a
 *            TALER_EXCHANGE_get_kyc_info_option_NAME(VALUE) helper
 * @return #GNUNET_OK on success,
 *         #GNUNET_NO on failure,
 *         #GNUNET_SYSERR on internal error
 */
#define TALER_EXCHANGE_get_kyc_info_set_options(gkih,...)              \
        TALER_EXCHANGE_get_kyc_info_set_options_ (                     \
          gkih,                                                         \
          TALER_EXCHANGE_COMMON_OPTIONS_ARRAY_MAX_SIZE,                 \
          ((const struct TALER_EXCHANGE_GetKycInfoOptionValue[])        \
           {__VA_ARGS__, TALER_EXCHANGE_get_kyc_info_option_end_ () }   \
          ))


/**
 * KYC info response.
 */
struct TALER_EXCHANGE_GetKycInfoResponse
{
  /**
   * HTTP response data.
   */
  struct TALER_EXCHANGE_HttpResponse hr;

  /**
   * Details depending on @e hr.http_status.
   */
  union
  {
    /**
     * Details if @e hr.http_status is #MHD_HTTP_OK.
     */
    struct
    {
      /**
       * Array of KYC requirements the client must satisfy.
       */
      const struct TALER_EXCHANGE_RequirementInformation *requirements;

      /**
       * Length of the @e requirements array.
       */
      size_t requirements_length;

      /**
       * Array of optional voluntary KYC checks available to the client.
       * Not implemented until protocol vATTEST.
       */
      const struct TALER_EXCHANGE_VoluntaryCheckInformation *vci;

      /**
       * Length of the @e vci array.
       */
      size_t vci_length;

      /**
       * True if ALL @e requirements must be fulfilled (AND combinator),
       * false if ANY one of the requirements suffices (OR combinator).
       */
      bool is_and_combinator;

    } ok;

  } details;

};


#ifndef TALER_EXCHANGE_GET_KYC_INFO_RESULT_CLOSURE
/**
 * Type of the closure used by
 * the #TALER_EXCHANGE_GetKycInfoCallback.
 */
#define TALER_EXCHANGE_GET_KYC_INFO_RESULT_CLOSURE void
#endif /* TALER_EXCHANGE_GET_KYC_INFO_RESULT_CLOSURE */

/**
 * Type of the function that receives the result of a
 * GET /kyc-info/$ACCESS_TOKEN request.
 *
 * @param cls closure
 * @param result result returned by the HTTP server
 */
typedef void
(*TALER_EXCHANGE_GetKycInfoCallback)(
  TALER_EXCHANGE_GET_KYC_INFO_RESULT_CLOSURE *cls,
  const struct TALER_EXCHANGE_GetKycInfoResponse *result);


/**
 * Start GET /kyc-info/$ACCESS_TOKEN operation.
 *
 * @param[in,out] gkih operation to start
 * @param cb function to call with the exchange's result
 * @param cb_cls closure for @a cb
 * @return status code, #TALER_EC_NONE on success
 */
enum TALER_ErrorCode
TALER_EXCHANGE_get_kyc_info_start (
  struct TALER_EXCHANGE_GetKycInfoHandle *gkih,
  TALER_EXCHANGE_GetKycInfoCallback cb,
  TALER_EXCHANGE_GET_KYC_INFO_RESULT_CLOSURE *cb_cls);


/**
 * Cancel GET /kyc-info/$ACCESS_TOKEN operation.  This function must not be
 * called by clients after the TALER_EXCHANGE_GetKycInfoCallback has been
 * invoked (as in those cases it'll be called internally by the
 * implementation already).
 *
 * @param[in] gkih operation to cancel
 */
void
TALER_EXCHANGE_get_kyc_info_cancel (
  struct TALER_EXCHANGE_GetKycInfoHandle *gkih);


#endif /* _TALER_EXCHANGE__GET_KYC_INFO_ACCESS_TOKEN_H */
