/*
  This file is part of TALER
  (C) 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 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/backenddb/set_instance.c
 * @brief Implementation of TALER_MERCHANTDB_set_instance
 * @author Christian Grothoff
 */
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_pq_lib.h>
#include <taler/taler_pq_lib.h>
#include "merchant-database/set_instance.h"
#include "helper.h"


enum GNUNET_DB_QueryStatus
TALER_MERCHANTDB_set_instance (
  struct TALER_MERCHANTDB_PostgresContext *pg,
  const char *instance_id)
{
  uint64_t serial;
  struct TALER_MerchantPublicKeyP merchant_pub;
  struct GNUNET_PQ_ResultSpec rs[] = {
    GNUNET_PQ_result_spec_uint64 ("merchant_serial",
                                  &serial),
    GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
                                          &merchant_pub),
    GNUNET_PQ_result_spec_end
  };
  enum GNUNET_DB_QueryStatus qs;
  char sp_sql[128];
  struct GNUNET_PQ_ExecuteStatement es[] = {
    GNUNET_PQ_make_execute (sp_sql),
    GNUNET_PQ_EXECUTE_STATEMENT_END
  };

  if (NULL == instance_id)
  {
    GNUNET_free (pg->current_merchant_id);
    pg->current_merchant_serial = 0;
    memset (&pg->current_merchant_pub,
            0,
            sizeof (pg->current_merchant_pub));
    return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
  }
  if ( (NULL != pg->current_merchant_id) &&
       (0 == strcmp (pg->current_merchant_id,
                     instance_id)) )
    return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
  PREPARE (pg,
           "set_instance_lookup_serial",
           "SELECT merchant_serial"
           "      ,merchant_pub"
           "  FROM merchant.merchant_instances"
           " WHERE merchant_id=$1");
  {
    struct GNUNET_PQ_QueryParam params[] = {
      GNUNET_PQ_query_param_string (instance_id),
      GNUNET_PQ_query_param_end
    };

    qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
                                                   "set_instance_lookup_serial",
                                                   params,
                                                   rs);
  }
  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
    return qs;
  GNUNET_snprintf (sp_sql,
                   sizeof (sp_sql),
                   "SET search_path TO merchant_instance_%llu",
                   (unsigned long long) serial);
  if (GNUNET_OK !=
      GNUNET_PQ_exec_statements (pg->conn,
                                 es))
  {
    GNUNET_break (0);
    return GNUNET_DB_STATUS_HARD_ERROR;
  }
  GNUNET_free (pg->current_merchant_id);
  pg->current_merchant_id = GNUNET_strdup (instance_id);
  pg->current_merchant_serial = serial;
  pg->current_merchant_pub = merchant_pub;
  return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
