/*
  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 src/backend/taler-merchant-httpd_get-private-groups.c
 * @brief implementation of GET /private/groups
 * @author Christian Grothoff
 */
#include "platform.h"
#include "taler-merchant-httpd_get-private-groups.h"
#include <taler/taler_json_lib.h>
#include "merchant-database/iterate_product_groups.h"

/**
 * Sensible bound on the number of results to return
 */
#define MAX_DELTA 1024


/**
 * Callback for listing product groups.
 *
 * @param cls closure with a `json_t *`
 * @param product_group_id unique identifier of the group
 * @param group_name name of the group
 * @param group_description human-readable description
 */
static void
add_group (void *cls,
           uint64_t product_group_id,
           const char *group_name,
           const char *group_description)
{
  json_t *groups = cls;
  json_t *entry;

  entry = GNUNET_JSON_PACK (
    GNUNET_JSON_pack_uint64 ("group_serial",
                             product_group_id),
    GNUNET_JSON_pack_string ("group_name",
                             group_name),
    GNUNET_JSON_pack_string ("description",
                             group_description));
  GNUNET_assert (NULL != entry);
  GNUNET_assert (0 ==
                 json_array_append_new (groups,
                                        entry));
}


enum MHD_Result
TMH_private_get_groups (const struct TMH_RequestHandler *rh,
                        struct MHD_Connection *connection,
                        struct TMH_HandlerContext *hc)
{
  int64_t limit = -20;
  uint64_t offset;
  json_t *groups;

  (void) rh;
  TALER_MHD_parse_request_snumber (connection,
                                   "limit",
                                   &limit);
  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");
  }
  if (limit > 0)
    offset = 0;
  else
    offset = INT64_MAX;
  TALER_MHD_parse_request_number (connection,
                                  "offset",
                                  &offset);

  groups = json_array ();
  GNUNET_assert (NULL != groups);

  {
    enum GNUNET_DB_QueryStatus qs;

    qs = TALER_MERCHANTDB_iterate_product_groups (TMH_db,
                                                  hc->instance->settings.id,
                                                  limit,
                                                  offset,
                                                  &add_group,
                                                  groups);
    if (qs < 0)
    {
      GNUNET_break (0);
      json_decref (groups);
      return TALER_MHD_reply_with_error (connection,
                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
                                         "iterate_product_groups");
    }
  }

  return TALER_MHD_REPLY_JSON_PACK (
    connection,
    MHD_HTTP_OK,
    GNUNET_JSON_pack_array_steal ("groups",
                                  groups));
}
