/*
   This file is part of TALER
   Copyright (C) 2022--2026 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/include/exchange-database/do_import_credits.h
 * @brief implementation of the do_import_credits function for Postgres
 * @author Christian Grothoff
 */
#ifndef EXCHANGE_DATABASE_DO_IMPORT_CREDITS_H
#define EXCHANGE_DATABASE_DO_IMPORT_CREDITS_H

#include "exchangedb_lib.h"


/**
 * Incoming wire transfer that credits a reserve.
 */
struct TALER_EXCHANGEDB_ReserveInInfo
{
  const struct TALER_ReservePublicKeyP *reserve_pub;
  const struct TALER_Amount *balance;
  struct GNUNET_TIME_Timestamp execution_time;
  struct TALER_FullPayto sender_account_details;
  uint64_t wire_reference;
};


/**
 * Incoming wire transfer that authenticates an account by carrying an
 * account public key in its subject.
 */
struct TALER_EXCHANGEDB_KycauthInInfo
{
  const union TALER_AccountPublicKeyP *account_pub;
  const struct TALER_Amount *balance;
  struct GNUNET_TIME_Timestamp execution_time;
  struct TALER_FullPayto sender_account_details;
  uint64_t wire_reference;
};


/**
 * Incoming WAD transfer from another exchange.
 */
struct TALER_EXCHANGEDB_WadInInfo
{
  const struct TALER_WadIdentifierP *wad_id;
  const char *origin_exchange_url;
  const struct TALER_Amount *balance;
  struct GNUNET_TIME_Timestamp execution_time;
};


/**
 * One batch of incoming wire transfers to import, together with the work
 * shard they were read under.  All transfers in a batch come from the same
 * bank account, which is why @e exchange_account_name is not per transfer.
 */
struct TALER_EXCHANGEDB_CreditBatch
{
  /**
   * Configuration section name of the exchange bank account the transfers
   * arrived at.
   */
  const char *exchange_account_name;

  /**
   * Transfers into reserves, may be NULL if @e reserves_length is 0.
   */
  const struct TALER_EXCHANGEDB_ReserveInInfo *reserves;

  /**
   * Length of the @e reserves array.
   */
  unsigned int reserves_length;

  /**
   * KYC authentication transfers, may be NULL if @e kycauths_length is 0.
   */
  const struct TALER_EXCHANGEDB_KycauthInInfo *kycauths;

  /**
   * Length of the @e kycauths array.
   */
  unsigned int kycauths_length;

  /**
   * WAD transfers, may be NULL if @e wads_length is 0.
   */
  const struct TALER_EXCHANGEDB_WadInInfo *wads;

  /**
   * Length of the @e wads array.
   */
  unsigned int wads_length;

  /**
   * Name of the job whose shard this batch was read under.
   */
  const char *job_name;

  /**
   * Inclusive start row of that shard.
   */
  uint64_t shard_start;

  /**
   * Exclusive end row of that shard.
   */
  uint64_t shard_end;

  /**
   * Row up to which (exclusive) the shard is done once this batch is in.
   * Pass @e shard_end to complete the shard.
   */
  uint64_t progress_row;

  /**
   * For how much longer we intend to hold the shard.
   */
  struct GNUNET_TIME_Relative lease;
};


/**
 * Import one batch of incoming wire transfers and advance the work shard it
 * belongs to.
 *
 * This is a single statement, so it needs no transaction of its own: the
 * transfers and the record of how far the shard has come either both land or
 * neither does.  That is what lets a caller commit as soon as the bank
 * answers, rather than holding everything open until the shard is finished.
 *
 * @param pg the database context
 * @param batch the transfers to import and the shard they belong to
 * @param[out] reserve_results set to the query status per entry of
 *          @a batch->reserves, must be of length @a batch->reserves_length;
 *          #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS means the transfer had
 *          already been imported
 * @return transaction status code; on success, the number of reserve
 *          transfers that were looked at
 */
enum GNUNET_DB_QueryStatus
TALER_EXCHANGEDB_do_import_credits (
  struct TALER_EXCHANGEDB_PostgresContext *pg,
  const struct TALER_EXCHANGEDB_CreditBatch *batch,
  enum GNUNET_DB_QueryStatus *reserve_results);

#endif
