/*
  This file is part of TALER
  Copyright (C) 2023 Taler Systems SA

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

  You should have received a copy of the GNU General Public License along with
  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
*/
/**
 * @file challenger/challenger-httpd.h
 * @brief OAuth 2.0 address validation server
 * @author Christian Grothoff
 */
#ifndef challenger_HTTPD_H
#define challenger_HTTPD_H

#include "platform.h"
#include <microhttpd.h>
#include <taler/taler_mhd_lib.h>
#include "challenger_database_lib.h"
#include <gnunet/gnunet_mhd_compat.h>


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

/**
 * Signature of a function used to clean up the context
 * of this handler.
 *
 * @param cls closure to clean up.
 */
typedef void
(*CH_ContextCleanup)(void *cls);


/**
 * Each MHD response handler that sets the "connection_cls" to a
 * non-NULL value must use a struct that has this struct as its first
 * member.  This struct contains a single callback, which will be
 * invoked to clean up the memory when the connection is completed.
 */
struct CH_HandlerContext
{

  /**
   * Function to execute the handler-specific cleanup of the
   * (typically larger) context.
   */
  CH_ContextCleanup cc;

  /**
   * Handler-specific context, will be passed to @e cc
   * upon completion.
   */
  void *ctx;

  /**
   * Connection being processed.
   */
  struct MHD_Connection *connection;

  /**
   * remaining URL path
   */
  const char *path;

  /**
   * Copy of our original full URL with query parameters.
   */
  char *full_url;

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

  /**
   * Asynchronous request context id.
   */
  struct GNUNET_AsyncScopeId async_scope_id;

};


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

  /**
   * URL the handler is for.  End with a '/' to make
   * this only a prefix to match. However, "/" will
   * only match "/" and not be treated as a prefix.
   */
  const char *url;

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

  /**
   * Function to call to handle the request.
   *
   * @param hc handler context
   * @param upload_data upload data
   * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
   * @return MHD result code
   */
  MHD_RESULT (*handler)(struct CH_HandlerContext *hc,
                        const char *upload_data,
                        size_t *upload_data_size);

};


/**
 * Handle to the database backend.
 */
extern struct CHALLENGER_DatabasePlugin *CH_db;

/**
 * Our context for making HTTP requests.
 */
extern struct GNUNET_CURL_Context *CH_ctx;

/**
 * Helper command to run for transmission of
 * challenge values.
 */
extern char *CH_auth_command;

/**
 * Type of addresses this challenger validates.
 */
extern char *CH_address_type;

/**
 * Hint to show to users on what address to enter.
 */
extern char *CH_address_hint;

/**
 * (external) base URL of this service.
 */
extern char *CH_base_url;

/**
 * Mustach template for the letter to send.
 * WARNING: not 0-terminated! Allocated via mmap(), free with munmap()!
 */
extern void *CH_message_template;

/**
 * Number of bytes in #CH_message_template
 */
extern size_t CH_message_template_len;

/**
 * How long is an individual validation request valid?
 */
extern struct GNUNET_TIME_Relative CH_validation_duration;

/**
 * How long validated data considered to be valid?
 */
extern struct GNUNET_TIME_Relative CH_validation_expiration;

/**
 * How often do we retransmit the challenge.
 */
extern struct GNUNET_TIME_Relative CH_pin_retransmission_frequency;

/**
 * JSON object with key-object pairs mapping address keys (from the
 * form) to an object with a field "regex" containing a regular
 * expressions expressing restrictions on values for the address and a
 * field "hint" (and possibly "hint_i18n") containing a human-readable
 * message explaining the restriction. Missing map entries indicate
 * that the input is unrestricted.
 */
extern json_t *CH_restrictions;

/**
 * Kick MHD to run now, to be called after MHD_resume_connection().
 * Basically, we need to explicitly resume MHD's event loop whenever
 * we made progress serving a request.  This function re-schedules
 * the task processing MHD's activities to run immediately.
 */
void
CH_trigger_daemon (void);


/**
 * Kick GNUnet Curl scheduler to begin curl interactions.
 */
void
CH_trigger_curl (void);


#endif
