/*
  This file is part of Anastasis
  Copyright (C) 2020, 2021, 2024 Anastasis SARL

  Anastasis 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.

  Anastasis 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
  Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
*/
/**
 * @file backend/anastasis-httpd_config.c
 * @brief headers for /terms handler
 * @author Christian Grothoff
 * @author Dennis Neufeld
 * @author Dominik Meister
 */
#include "platform.h"
#include <jansson.h>
#include "anastasis-httpd_config.h"
#include "anastasis-httpd.h"
#include <taler/taler_json_lib.h>
#include "anastasis_authorization_lib.h"


/**
 * Add enabled methods and their fees to the ``/config`` response.
 *
 * @param[in,out] cls a `json_t` array to build
 * @param section configuration section to inspect
 */
static void
add_methods (void *cls,
             const char *section)
{
  json_t *method_arr = cls;
  struct ANASTASIS_AuthorizationPlugin *p;
  json_t *method;

  if (0 != strncasecmp (section,
                        "authorization-",
                        strlen ("authorization-")))
    return;
  if (GNUNET_YES !=
      GNUNET_CONFIGURATION_get_value_yesno (AH_cfg,
                                            section,
                                            "ENABLED"))
    return;
  section += strlen ("authorization-");
  p = ANASTASIS_authorization_plugin_load (section,
                                           AH_cfg);
  if (NULL == p)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to load authorization plugin `%s'\n",
                section);
    return;
  }
  method = GNUNET_JSON_PACK (
    GNUNET_JSON_pack_string ("type",
                             section),
    TALER_JSON_pack_amount ("cost",
                            AH_primary_price (&p->costs)),
    TALER_JSON_pack_amount_list ("costs",
                                 &p->costs));
  GNUNET_assert (
    0 ==
    json_array_append_new (method_arr,
                           method));
}


enum MHD_Result
AH_handler_config (struct AH_RequestHandler *rh,
                   struct MHD_Connection *connection)
{
  static struct MHD_Response *response;

  if (NULL == response)
  {
    json_t *method_arr = json_array ();
    json_t *currency_arr = json_array ();

    GNUNET_assert (NULL != method_arr);
    GNUNET_assert (NULL != currency_arr);
    for (unsigned int i = 0; i<AH_currencies_len; i++)
      GNUNET_assert (0 ==
                     json_array_append_new (currency_arr,
                                            json_string (AH_currencies[i])));
    {
      json_t *method;

      method = GNUNET_JSON_PACK (
        GNUNET_JSON_pack_string ("type",
                                 "question"),
        TALER_JSON_pack_amount ("cost",
                                AH_primary_price (&AH_question_costs)),
        TALER_JSON_pack_amount_list ("costs",
                                     &AH_question_costs));
      GNUNET_assert (
        0 ==
        json_array_append_new (method_arr,
                               method));
    }
    GNUNET_CONFIGURATION_iterate_sections (AH_cfg,
                                           &add_methods,
                                           method_arr);

    response = TALER_MHD_MAKE_JSON_PACK (
      GNUNET_JSON_pack_string ("name",
                               "anastasis"),
      /* Deliberately incompatible with 0:x:x: the key derivation was fixed to
         use the full context string, so every key derived by an older client
         differs and backups made with one cannot be recovered by the other.
         3 adds the plural "…s" fields and "currencies" without removing
         anything, so the age stays at 1 and a version 2 client still works
         against us, seeing only the primary currency. */
      GNUNET_JSON_pack_string ("version",
                               "3:0:1"),
      GNUNET_JSON_pack_string ("build_version",
                               PACKAGE_VERSION),
      GNUNET_JSON_pack_string ("implementation",
                               "urn:net:taler:specs:anastasis:c-reference"),
      GNUNET_JSON_pack_string ("business_name",
                               AH_business_name),
      GNUNET_JSON_pack_array_steal ("methods",
                                    method_arr),
      GNUNET_JSON_pack_uint64 ("storage_limit_in_megabytes",
                               AH_upload_limit_mb),
      GNUNET_JSON_pack_array_steal ("currencies",
                                    currency_arr),
      /* The scalar fields report the primary currency and stay for the
         benefit of version 2 clients; the plural ones carry the full
         list. */
      TALER_JSON_pack_amount ("annual_fee",
                              AH_primary_price (&AH_annual_fees)),
      TALER_JSON_pack_amount_list ("annual_fees",
                                   &AH_annual_fees),
      TALER_JSON_pack_amount ("truth_upload_fee",
                              AH_primary_price (&AH_truth_upload_fees)),
      TALER_JSON_pack_amount_list ("truth_upload_fees",
                                   &AH_truth_upload_fees),
      TALER_JSON_pack_amount ("liability_limit",
                              AH_primary_price (&AH_insurance)),
      TALER_JSON_pack_amount_list ("liability_limits",
                                   &AH_insurance),
      GNUNET_JSON_pack_data_auto ("provider_salt",
                                  &AH_provider_salt));
  }
  return MHD_queue_response (connection,
                             MHD_HTTP_OK,
                             response);
}


/* end of anastasis-httpd_config.c */
