/*
  This file is part of TALER
  Copyright (C) 2024 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 donau-httpd.h
 * @brief Global declarations for the donau
 * @author Florian Dold
 * @author Benedikt Mueller
 * @author Christian Grothoff
 */
#ifndef DONAU_HTTPD_H
#define DONAU_HTTPD_H

#include <microhttpd.h>
#include <taler/taler_json_lib.h>
#include <taler/taler_util.h>
#include <gnunet/gnunet_mhd_compat.h>


/**
 * How long is caching /keys allowed at most?
 */
// extern struct GNUNET_TIME_Relative DH_max_keys_caching;

/**
 * The donau's configuration.
 */
extern const struct GNUNET_CONFIGURATION_Handle *DH_cfg;

/**
 * Main directory with donau data.
 */
extern char *DH_donau_directory;

/**
 * Legal domain for this donau, to be shown to the user.
 */
extern char *DH_legal_domain;

/**
 * True if we should commit suicide once all active
 * connections are finished. Also forces /keys requests
 * to terminate if they are long-polling.
 */
extern bool DH_suicide;

/**
 * Value to return from main()
 */
extern int DH_global_ret;

/**
 * Our DB plugin.
 */
extern struct DONAUDB_Plugin *DH_plugin;

/**
 * Our currency.
 */
extern char *DH_currency;

/**
 * Protocol version.
 */
extern char *DONAU_PROTOCOL_VERSION;

/**
 * Our (externally visible) base URL.
 */
extern char *DH_base_url;

/**
 * Are we shutting down?
 */
extern volatile bool MHD_terminating;

/**
 * Context for all CURL operations (useful to the event loop)
 */
extern struct GNUNET_CURL_Context *DH_curl_ctx;

/**
 * @brief Struct describing an URL and the handler for it.
 */
struct DH_RequestHandler;


/**
 * @brief Context in which the donau is processing
 *        all requests
 */
struct DH_RequestContext
{

  /**
   * Async Scope ID associated with this request.
   */
  struct GNUNET_AsyncScopeId async_scope_id;

  /**
   * When was this request started?
   */
  struct GNUNET_TIME_Absolute start_time;

  /**
   * Opaque parsing context.
   */
  void *opaque_post_parsing_context;

  /**
   * Request handler responsible for this request.
   */
  const struct DH_RequestHandler *rh;

  /**
   * Request URL (for logging).
   */
  const char *url;

  /**
   * Connection we are processing.
   */
  struct MHD_Connection *connection;

  /**
   * @e rh-specific cleanup routine. Function called
   * upon completion of the request that should
   * clean up @a rh_ctx. Can be NULL.
   */
  void
  (*rh_cleaner)(struct DH_RequestContext *rc);

  /**
   * @e rh-specific context. Place where the request
   * handler can associate state with this request.
   * Can be NULL.
   */
  void *rh_ctx;
};


/**
 * @brief Struct describing an URL and the handler for it.
 */
struct DH_RequestHandler
{

  /**
   * URL the handler is for (first part only).
   */
  const char *url;

  /**
   * Method the handler is for.
   */
  const char *method;

  /**
   * True if HTTP authorization via Bearer token is required.
   */
  bool needs_authorization;

  /**
   * Callbacks for handling of the request. Which one is used
   * depends on @e method.
   */
  union
  {
    /**
     * Function to call to handle GET requests (and those
     * with @e method NULL).
     *
     * @param rc context for the request
     * @param args array of arguments, needs to be of length @e args_expected
     * @return MHD result code
     */
    MHD_RESULT
    (*get)(struct DH_RequestContext *rc,
           const char *const args[]);


    /**
     * Function to call to handle POST requests.
     *
     * @param rc context for the request
     * @param json uploaded JSON data
     * @param args array of arguments, needs to be of length @e nargs
     * @return MHD result code
     */
    MHD_RESULT
    (*post)(struct DH_RequestContext *rc,
            const json_t *root,
            const char *const args[]);

    /**
     * Function to call to handle PATCH requests.
     *
     * @param rc context for the request
     * @param json uploaded JSON data
     * @param args array of arguments, needs to be of length @e nargs
     * @return MHD result code
     */
    MHD_RESULT
    (*patch)(struct DH_RequestContext *rc,
             const json_t *root,
             const char *const args[]);

    /**
     * Function to call to handle DELETE requests.
     *
     * @param rc context for the request
     * @param args array of arguments, needs to be of length @e nargs
     * @return MHD result code
     */
    MHD_RESULT
      (*delete)(struct DH_RequestContext *rc,
                const char *const args[]);

  } handler;

  /**
   * Mime type to use in reply (hint, can be NULL).
   */
  const char *mime_type;

  /**
   * Raw data for the @e handler, can be NULL for none provided.
   */
  const void *data;

  /**
   * Number of bytes in @e data, 0 for data is 0-terminated (!).
   */
  size_t data_size;

  /**
   * Default response code. 0 for none provided.
   */
  unsigned int response_code;

  /**
   * Number of arguments this handler expects in the @a args array.
   */
  unsigned int nargs;

  /**
   * Is the number of arguments given in @e nargs only an upper bound,
   * and calling with fewer arguments could be OK?
   */
  bool nargs_is_upper_bound;
};

/**
 * Function to call to handle requests to "/keys" by sending
 * back our current key material.
 *
 * @param rc request context
 * @param args array of additional options (must be empty for this function)
 * @return MHD result code
 */
// MHD_RESULT
// DH_keys_get_handler (struct DH_RequestContext *rc,
//                     const char *const args[]);


#endif
