/*
  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 Lesser General Public License as published by the Free Software
  Foundation; either version 2.1, 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 Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with
  TALER; see the file COPYING.LGPL.  If not, see
  <http://www.gnu.org/licenses/>
*/
/**
 * @file include/taler/taler-merchant/post-private-orders.h
 * @brief C interface for POST /private/orders of the merchant backend
 * @author Christian Grothoff
 * @author Marcello Stanisci
 */
#ifndef _TALER_MERCHANT__POST_PRIVATE_ORDERS_H
#define _TALER_MERCHANT__POST_PRIVATE_ORDERS_H

#include <taler/taler-merchant/common.h>


/**
 * Handle for a POST /private/orders request.
 */
struct TALER_MERCHANT_PostOrdersHandle;


/**
 * One inventory product entry for POST /orders.
 */
struct TALER_MERCHANT_InventoryProduct
{

  /**
   * Identifier of the product in the inventory.
   */
  const char *product_id;

  /**
   * How many units of this product should be ordered.
   */
  uint64_t quantity;

  /**
   * Fractional component of the quantity in units of 1/1000000 of the
   * base value.
   */
  uint32_t quantity_frac;

  /**
   * Set to true if this product uses fractional quantity fields.
   */
  bool use_fractional_quantity;

};


/**
 * Response details for a POST /private/orders request.
 */
struct TALER_MERCHANT_PostOrdersReply
{

  /**
   * HTTP response details.
   */
  struct TALER_MERCHANT_HttpResponse hr;

  /**
   * Details depending on the HTTP status code.
   */
  union
  {

    /**
     * Details on #MHD_HTTP_OK.
     */
    struct
    {

      /**
       * The assigned order identifier.
       */
      const char *order_id;

      /**
       * Claim token for the order, or NULL if none was issued.
       */
      const struct TALER_ClaimTokenP *token;

      /**
       * Deadline by which the wallet must pay (may be zero for old backends).
       */
      struct GNUNET_TIME_Timestamp pay_deadline;

    } ok;

    /**
     * Details on #MHD_HTTP_GONE (product out of stock).
     */
    struct
    {

      /**
       * Identifier of the product that ran out of stock.
       */
      const char *product_id;

      /**
       * Quantity that was requested.
       */
      uint64_t requested_quantity;

      /**
       * Fractional part of the requested quantity.
       */
      uint32_t requested_quantity_frac;

      /**
       * Quantity that is available.
       */
      uint64_t available_quantity;

      /**
       * Fractional part of the available quantity.
       */
      uint32_t available_quantity_frac;

      /**
       * When restocking is expected (may be zero/unset).
       */
      struct GNUNET_TIME_Timestamp restock_expected;

    } gone;

  } details;

};


/**
 * Callback for a POST /private/orders request.
 *
 * @param cls closure
 * @param por response details
 */
typedef void
(*TALER_MERCHANT_PostOrdersCallback)(
  void *cls,
  const struct TALER_MERCHANT_PostOrdersReply *por);


/**
 * Issue a POST /private/orders request (simple form).
 *
 * @param ctx CURL context to use
 * @param backend_url base URL of the merchant backend
 * @param order JSON object describing the order
 * @param refund_delay refund delay for this order
 * @param cb callback to invoke with the result
 * @param cb_cls closure for @a cb
 * @return handle for the request, NULL on hard error
 */
struct TALER_MERCHANT_PostOrdersHandle *
TALER_MERCHANT_orders_post (struct GNUNET_CURL_Context *ctx,
                            const char *backend_url,
                            const json_t *order,
                            struct GNUNET_TIME_Relative refund_delay,
                            TALER_MERCHANT_PostOrdersCallback cb,
                            void *cb_cls);


/**
 * Issue a POST /private/orders request with extended options.
 *
 * @param ctx CURL context to use
 * @param backend_url base URL of the merchant backend
 * @param order JSON object describing the order
 * @param refund_delay refund delay for this order
 * @param payment_target desired payment target, or NULL for default
 * @param inventory_products_length number of entries in @a inventory_products
 * @param inventory_products array of inventory products to lock
 * @param uuids_length number of entries in @a uuids
 * @param uuids array of idempotency UUIDs
 * @param create_token whether to create a claim token
 * @param cb callback to invoke with the result
 * @param cb_cls closure for @a cb
 * @return handle for the request, NULL on hard error
 */
struct TALER_MERCHANT_PostOrdersHandle *
TALER_MERCHANT_orders_post2 (
  struct GNUNET_CURL_Context *ctx,
  const char *backend_url,
  const json_t *order,
  struct GNUNET_TIME_Relative refund_delay,
  const char *payment_target,
  unsigned int inventory_products_length,
  const struct TALER_MERCHANT_InventoryProduct inventory_products[],
  unsigned int uuids_length,
  const char *uuids[],
  bool create_token,
  TALER_MERCHANT_PostOrdersCallback cb,
  void *cb_cls);


/**
 * Issue a POST /private/orders request with all options.
 *
 * @param ctx CURL context to use
 * @param backend_url base URL of the merchant backend
 * @param order JSON object describing the order
 * @param session_id session identifier, or NULL
 * @param refund_delay refund delay for this order
 * @param payment_target desired payment target, or NULL for default
 * @param inventory_products_length number of entries in @a inventory_products
 * @param inventory_products array of inventory products to lock
 * @param uuids_length number of entries in @a uuids
 * @param uuids array of idempotency UUIDs
 * @param create_token whether to create a claim token
 * @param cb callback to invoke with the result
 * @param cb_cls closure for @a cb
 * @return handle for the request, NULL on hard error
 */
struct TALER_MERCHANT_PostOrdersHandle *
TALER_MERCHANT_orders_post3 (
  struct GNUNET_CURL_Context *ctx,
  const char *backend_url,
  const json_t *order,
  const char *session_id,
  struct GNUNET_TIME_Relative refund_delay,
  const char *payment_target,
  unsigned int inventory_products_length,
  const struct TALER_MERCHANT_InventoryProduct inventory_products[],
  unsigned int uuids_length,
  const char *uuids[],
  bool create_token,
  TALER_MERCHANT_PostOrdersCallback cb,
  void *cb_cls);


/**
 * Cancel a POST /private/orders request.
 *
 * @param[in] po handle to cancel
 */
void
TALER_MERCHANT_orders_post_cancel (
  struct TALER_MERCHANT_PostOrdersHandle *po);


#endif
