/*
 This file is part of GNU Taler
 (C) 2024 Taler Systems S.A.

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

 GNU 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
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */

/**
 * Imports.
 */
import {
  Configuration,
  j2s,
  Logger,
  TransactionMajorState,
  TransactionMinorState,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import {
  configureCommonKyc,
  createKycTestkudosEnvironment,
  withdrawViaBankV3,
} from "../harness/environments.js";
import { GlobalTestState } from "../harness/harness.js";

const logger = new Logger(`test-kyc-merchant-deposit.ts`);

const myAmlConfig = `
# Fallback measure on errors.
[kyc-measure-freeze-investigate]
CHECK_NAME = skip
PROGRAM = freeze-investigate
VOLUNTARY = NO
CONTEXT = {}

[aml-program-freeze-investigate]
DESCRIPTION = "Fallback measure on errors that freezes the account and asks AML staff to investigate the system failure."
COMMAND = taler-exchange-helper-measure-freeze
ENABLED = YES
FALLBACK = freeze-investigate

[aml-program-inform-investigate]
DESCRIPTION = "Measure that asks AML staff to investigate an account and informs the account owner about it."
COMMAND = taler-exchange-helper-measure-inform-investigate
ENABLED = YES
FALLBACK = freeze-investigate

[kyc-check-form-gls-merchant-onboarding]
TYPE = FORM
FORM_NAME = gls-merchant-onboarding
DESCRIPTION = "GLS Merchant Onboarding"
DESCRIPTION_I18N = {}
OUTPUTS =
FALLBACK = freeze-investigate

[kyc-measure-merchant-onboarding]
CHECK_NAME = form-gls-merchant-onboarding
PROGRAM = inform-investigate
CONTEXT = {}
VOLUNTARY = NO

[kyc-rule-deposit-limit-zero]
OPERATION_TYPE = DEPOSIT
NEXT_MEASURES = merchant-onboarding
EXPOSED = YES
ENABLED = YES
THRESHOLD = TESTKUDOS:0
TIMEFRAME = "1 days"
`;

function adjustExchangeConfig(config: Configuration) {
  configureCommonKyc(config);
  config.loadFromString(myAmlConfig);
}

export async function runKycWalletDepositAbortTest(t: GlobalTestState) {
  // Set up test environment

  const {
    merchant,
    bankClient,
    exchange,
    exchangeBankAccount,
    wireGatewayApi,
    walletClient,
  } = await createKycTestkudosEnvironment(t, {
    adjustExchangeConfig,
  });

  const wres = await withdrawViaBankV3(t, {
    walletClient,
    bankClient,
    exchange,
    amount: "TESTKUDOS:20",
  });
  await wres.withdrawalFinishedCond;

  const depositPaytoUri = wres.accountPaytoUri;

  const depositResp = await walletClient.call(
    WalletApiOperation.CreateDepositGroup,
    {
      amount: "TESTKUDOS:5",
      depositPaytoUri,
    },
  );

  await walletClient.call(WalletApiOperation.TestingWaitTransactionState, {
    transactionId: depositResp.transactionId,
    txState: {
      major: TransactionMajorState.Pending,
      minor: TransactionMinorState.KycRequired,
    },
  });

  {
    const bal = await walletClient.call(WalletApiOperation.GetBalances, {});
    console.log(`balance in kyc: ${j2s(bal)}`);
    t.assertAmountEquals(bal.balances[0].pendingOutgoing, "TESTKUDOS:5");
    t.assertAmountEquals(bal.balances[0].pendingIncoming, "TESTKUDOS:0");
  }

  await walletClient.call(WalletApiOperation.AbortTransaction, {
    transactionId: depositResp.transactionId,
  });

  await walletClient.call(WalletApiOperation.TestingWaitTransactionState, {
    transactionId: depositResp.transactionId,
    txState: {
      major: TransactionMajorState.Aborted,
      minor: "*",
    },
  });

  // Also wait for potential refreshes
  await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});

  const bal = await walletClient.call(WalletApiOperation.GetBalances, {});
  console.log(j2s(bal));

  t.assertDeepEqual(bal.balances[0].available, "TESTKUDOS:18.93");
}

runKycWalletDepositAbortTest.suites = ["wallet", "kyc"];
