/*
  This file is part of TALER
  Copyright (C) 2015 Christian Grothoff (and other contributing authors)
  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, If not, see
  
*/
/**
 * @file mint-lib/mint_api_common.c
 * @brief common functions for the mint API
 * @author Christian Grothoff
 */
#include "platform.h"
#include "mint_api_common.h"
#include "mint_api_json.h"
#include "mint_api_context.h"
#include "mint_api_handle.h"
#include "taler_signatures.h"
/**
 * Verify a coins transaction history as returned by the mint.
 *
 * @param currency expected currency for the coin
 * @param coin_pub public key of the coin
 * @param history history of the coin in json encoding
 * @param[out] total how much of the coin has been spent according to @a history
 * @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not
 */
int
TALER_MINT_verify_coin_history_ (const char *currency,
                                 const struct TALER_CoinSpendPublicKeyP *coin_pub,
                                 json_t *history,
                                 struct TALER_Amount *total)
{
  size_t len;
  size_t off;
  if (NULL == history)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  len = json_array_size (history);
  if (0 == len)
  {
    GNUNET_break_op (0);
    return GNUNET_SYSERR;
  }
  TALER_amount_get_zero (currency,
                         total);
  for (off=0;offeddsa_pub),
      MAJ_spec_end
    };
    transaction = json_array_get (history,
                                  off);
    if (GNUNET_OK !=
        MAJ_parse_json (transaction,
                        spec))
    {
      GNUNET_break_op (0);
      return GNUNET_SYSERR;
    }
    switch (ntohl (purpose->purpose))
    {
    case TALER_SIGNATURE_WALLET_COIN_DEPOSIT:
      {
        const struct TALER_DepositRequestPS *dr;
        struct TALER_Amount dr_amount;
        if (ntohl (purpose->size) != sizeof (struct TALER_DepositRequestPS))
        {
          GNUNET_break (0);
          MAJ_parse_free (spec);
          return GNUNET_SYSERR;
        }
        dr = (const struct TALER_DepositRequestPS *) purpose;
        TALER_amount_ntoh (&dr_amount,
                           &dr->amount_with_fee);
        if (0 != TALER_amount_cmp (&dr_amount,
                                   &amount))
        {
          GNUNET_break (0);
          MAJ_parse_free (spec);
          return GNUNET_SYSERR;
        }
      }
      break;
    case TALER_SIGNATURE_WALLET_COIN_MELT:
      {
        const struct TALER_RefreshMeltCoinAffirmationPS *rm;
        struct TALER_Amount rm_amount;
        if (ntohl (purpose->size) != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
        {
          GNUNET_break (0);
          MAJ_parse_free (spec);
          return GNUNET_SYSERR;
        }
        rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) purpose;
        TALER_amount_ntoh (&rm_amount,
                           &rm->amount_with_fee);
        if (0 != TALER_amount_cmp (&rm_amount,
                                   &amount))
        {
          GNUNET_break (0);
          MAJ_parse_free (spec);
          return GNUNET_SYSERR;
        }
      }
      break;
    default:
      /* signature not supported, new version on server? */
      GNUNET_break (0);
      MAJ_parse_free (spec);
      return GNUNET_SYSERR;
    }
    if (GNUNET_OK !=
        TALER_amount_add (total,
                          total,
                          &amount))
    {
      /* overflow in history already!? inconceivable! Bad mint! */
      GNUNET_break_op (0);
      MAJ_parse_free (spec);
      return GNUNET_SYSERR;
    }
    MAJ_parse_free (spec);
  }
  return GNUNET_OK;
}
/* end of mint_api_common.c */