/*
  This file is part of TALER
  (C) 2025 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 taler-merchant-httpd_get-private-pots.c
 * @brief implementation of GET /private/pots
 * @author Christian Grothoff
 */
#include "taler/platform.h"
#include "taler-merchant-httpd_get-private-pots.h"
#include <taler/taler_json_lib.h>


/**
 * Sensible bound on the limit.
 */
#define MAX_DELTA 1024


/**
 * Callback for listing money pots.
 *
 * @param cls closure with a `json_t *`
 * @param money_pot_id unique identifier of the pot
 * @param name name of the pot
 * @param description human-readable description (ignored for listing)
 * @param pot_total_len length of the @a pot_totals array
 * @param pot_totals current total amounts in the pot
 */
static void
add_pot (void *cls,
         uint64_t money_pot_id,
         const char *name,
         size_t pot_total_len,
         const struct TALER_Amount *pot_totals)
{
  json_t *pots = cls;
  json_t *entry;

  entry = GNUNET_JSON_PACK (
    GNUNET_JSON_pack_uint64 ("pot_serial",
                             money_pot_id),
    GNUNET_JSON_pack_string ("pot_name",
                             name),
    (0 == pot_total_len)
    ? GNUNET_JSON_pack_array_steal ("pot_totals",
                                    json_array ())
    : TALER_JSON_pack_amount_array ("pot_totals",
                                    pot_total_len,
                                    pot_totals));
  GNUNET_assert (NULL != entry);
  GNUNET_assert (0 ==
                 json_array_append_new (pots,
                                        entry));
}


MHD_RESULT
TMH_private_get_pots (const struct TMH_RequestHandler *rh,
                      struct MHD_Connection *connection,
                      struct TMH_HandlerContext *hc)
{
  int64_t limit = -20;
  uint64_t offset;
  json_t *pots;

  (void) rh;
  TALER_MHD_parse_request_snumber (connection,
                                   "limit",
                                   &limit);
  if (limit > 0)
    offset = 0;
  else
    offset = INT64_MAX;
  TALER_MHD_parse_request_number (connection,
                                  "offset",
                                  &offset);
  if ( (-MAX_DELTA > limit) ||
       (limit > MAX_DELTA) )
  {
    GNUNET_break_op (0);
    return TALER_MHD_reply_with_error (connection,
                                       MHD_HTTP_BAD_REQUEST,
                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
                                       "limit");
  }

  pots = json_array ();
  GNUNET_assert (NULL != pots);
  {
    enum GNUNET_DB_QueryStatus qs;

    qs = TMH_db->select_money_pots (TMH_db->cls,
                                    hc->instance->settings.id,
                                    limit,
                                    offset,
                                    &add_pot,
                                    pots);
    if (qs < 0)
    {
      GNUNET_break (0);
      json_decref (pots);
      return TALER_MHD_reply_with_error (connection,
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
                                         "select_money_pots");
    }
  }
  return TALER_MHD_REPLY_JSON_PACK (
    connection,
    MHD_HTTP_OK,
    GNUNET_JSON_pack_array_steal ("pots",
                                  pots));
}
