/*
   This file is part of TALER
   Copyright (C) 2022 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 begin_rule_update.h
 * @brief implementation to update rules for an account
 * @author Christian Grothoff
 */
#ifndef EXCHANGE_DATABASE_BEGIN_RULE_UPDATE_H
#define EXCHANGE_DATABASE_BEGIN_RULE_UPDATE_H

#include "taler/taler_util.h"
#include "taler/taler_json_lib.h"
#include "exchangedb_lib.h"


/**
 * Handle for helper logic that advances rules to the currently
 * valid rule set.
 */
struct TALER_EXCHANGEDB_RuleUpdater;

/**
 * Main result returned in the
 * #TALER_EXCHANGEDB_CurrentRulesCallback
 */
struct TALER_EXCHANGEDB_RuleUpdaterResult
{
  /**
   * Row the rule set is based on.
   */
  uint64_t legitimization_outcome_last_row;

  /**
   * Current legitimization rule set, owned by callee.  Will be NULL on error
   * or for default rules. Will not contain skip rules and not be expired.
   */
  struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs;

  /**
   * Hint to return, if @e ec is not #TALER_EC_NONE. Can be NULL.
   */
  const char *hint;

  /**
   * Error code in case a problem was encountered
   * when fetching or updating the legitimization rules.
   */
  enum TALER_ErrorCode ec;
};


/**
 * Function called with the current rule set.
 *
 * @param cls closure
 * @param rur includes legitimziation rule set that applies to the account
 *   (owned by callee, callee must free the lrs!)
 */
#ifndef TALER_EXCHANGEDB_CURRENT_RULES_RESULT_CLOSURE
/**
 * Type of the closure for #TALER_EXCHANGEDB_CurrentRulesCallback.
 */
#define TALER_EXCHANGEDB_CURRENT_RULES_RESULT_CLOSURE void
#endif
typedef void
(*TALER_EXCHANGEDB_CurrentRulesCallback)(
  TALER_EXCHANGEDB_CURRENT_RULES_RESULT_CLOSURE *cls,
  struct TALER_EXCHANGEDB_RuleUpdaterResult *rur);


/**
 * Obtains the current rule set for an account and advances it
 * to the rule set that should apply right now. Considers
 * expiration of rules as well as "skip" measures. Runs
 * AML programs as needed to advance the rule book to the currently
 * valid state.
 *
 * On success, the result is returned in a (fresh) transaction
 * that must be committed for the result to be valid. This should
 * be used to ensure transactionality of the AML program result.
 *
 * This function should be called *outside* of any other transaction.
 * Calling it while a transaction is already running risks aborting
 * that transaction.
 *
 * @param pg database plugin to use
 * @param attribute_key key to use to decrypt attributes
 * @param account account to get the rule set for
 * @param is_wallet true if @a account is a wallet
 * @param cb function to call with the result
 * @param cb_cls closure for @a cb
 * @return handle to cancel the operation
 */
struct TALER_EXCHANGEDB_RuleUpdater *
TALER_EXCHANGEDB_begin_rule_update (
  struct TALER_EXCHANGEDB_PostgresContext *pg,
  const struct TALER_AttributeEncryptionKeyP *attribute_key,
  const struct TALER_NormalizedPaytoHashP *account,
  bool is_wallet,
  TALER_EXCHANGEDB_CurrentRulesCallback cb,
  TALER_EXCHANGEDB_CURRENT_RULES_RESULT_CLOSURE *cb_cls);


/**
 * Cancel operation to get the current legitimization rule set.
 *
 * @param[in] ru operation to cancel
 */
void
TALER_EXCHANGEDB_begin_rule_update_cancel (
  struct TALER_EXCHANGEDB_RuleUpdater *ru);


#endif
