/*
  This file is part of GNU Taler
  Copyright (C) 2024, 2025 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 src/util/product_sold_serialize.c
 * @brief shared logic for product sold serialization
 * @author Iván Ávalos
 * @author Christian Grothoff
 */
#include "platform.h"
#include <gnunet/gnunet_json_lib.h>
#include <gnunet/gnunet_common.h>
#include <taler/taler_json_lib.h>
#include <jansson.h>
#include "taler/taler_util.h"
#include "taler/taler_merchant_util.h"


/**
 * Convert quantity @a q into a string for JSON serialization
 *
 * @param q quantity to convert
 * @return formatted string
 */
static const char *
quantity_to_string (const struct TALER_MERCHANT_ProductQuantity *q)
{
  static TALER_THREAD_LOCAL char res[64];

  TALER_MERCHANT_vk_format_fractional_string (TALER_MERCHANT_VK_QUANTITY,
                                              q->integer,
                                              q->fractional,
                                              sizeof (res),
                                              res);
  return res;
}


json_t *
TALER_MERCHANT_product_sold_serialize (
  const struct TALER_MERCHANT_ProductSold *p)
{
  json_t *prices;

  prices = json_array ();
  GNUNET_assert (NULL != prices);
  for (unsigned int i = 0; i<p->prices_length; i++)
    GNUNET_assert (0 ==
                   json_array_append_new (prices,
                                          TALER_JSON_from_amount (
                                            &p->prices[i])));
  return GNUNET_JSON_PACK (
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_string ("product_id",
                               p->product_id)),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_string ("product_name",
                               p->product_name)),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_string ("description",
                               p->description)),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_object_incref ("description_i18n",
                                      (json_t *) p->description_i18n)),
    GNUNET_JSON_pack_conditional (
      (0 != p->unit_quantity.integer) ||
      (0 != p->unit_quantity.fractional),
      GNUNET_JSON_pack_string ("unit_quantity",
                               quantity_to_string (&p->unit_quantity))),
    /* Legacy */
    GNUNET_JSON_pack_conditional (
      0 == p->unit_quantity.fractional,
      GNUNET_JSON_pack_uint64 ("quantity",
                               p->unit_quantity.integer)),
    GNUNET_JSON_pack_bool ("prices_are_net",
                           p->prices_are_net),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_string ("unit",
                               p->unit)),
    /* Deprecated, use prices! */
    GNUNET_JSON_pack_allow_null (
      TALER_JSON_pack_amount ("price",
                              0 < p->prices_length
                              ? &p->prices[0]
                              : NULL)),
    GNUNET_JSON_pack_array_steal ("prices",
                                  prices),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_string ("image",
                               p->image)),
    GNUNET_JSON_pack_allow_null (
      GNUNET_JSON_pack_array_incref ("taxes",
                                     (json_t *) p->taxes)),
    GNUNET_JSON_pack_conditional (
      ! (GNUNET_TIME_absolute_is_zero (p->delivery_date.abs_time) ||
         GNUNET_TIME_absolute_is_never (p->delivery_date.abs_time)),
      GNUNET_JSON_pack_timestamp ("delivery_date",
                                  p->delivery_date)),
    GNUNET_JSON_pack_uint64 ("product_money_pot",
                             p->product_money_pot));
}
