/*
 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,
  encodeCrock,
  getRandomBytes,
  hashNormalizedPaytoUri,
  j2s,
  succeedOrThrow,
  TalerWireGatewayHttpClient,
} from "@gnu-taler/taler-util";
import { createSyncCryptoApi } from "@gnu-taler/taler-wallet-core";
import {
  configureCommonKyc,
  createKycTestkudosEnvironment,
} from "../harness/environments.js";
import {
  getTestHarnessPaytoForLabel,
  GlobalTestState,
} from "../harness/harness.js";

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:1
TIMEFRAME = "1 days"
`;

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

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

  const { bankClient, exchangeBankAccount, exchangeApi, bank } =
    await createKycTestkudosEnvironment(t, { adjustExchangeConfig });

  const merchantPayto = getTestHarnessPaytoForLabel("merchant-default");

  await bankClient.registerAccountExtended({
    name: "merchant-default",
    password: encodeCrock(getRandomBytes(32)),
    username: "merchant-default",
    payto_uri: merchantPayto,
  });

  const cryptoApi = createSyncCryptoApi();

  const wireGatewayApiClient = new TalerWireGatewayHttpClient(
    exchangeBankAccount.wireGatewayApiBaseUrl,
  );

  const kycPaytoHash = encodeCrock(hashNormalizedPaytoUri(merchantPayto));

  const merchantPair1 = await cryptoApi.createEddsaKeypair({});
  const merchantPair2 = await cryptoApi.createEddsaKeypair({});

  await wireGatewayApiClient.addKycAuth({
    body: {
      account_pub: merchantPair1.pub,
      amount: "TESTKUDOS:0.1",
      debit_account: merchantPayto,
    },
    auth: bank.getAdminAuth(),
  });

  await wireGatewayApiClient.addKycAuth({
    body: {
      account_pub: merchantPair2.pub,
      amount: "TESTKUDOS:0.1",
      debit_account: merchantPayto,
    },
    auth: bank.getAdminAuth(),
  });

  {
    const sigResp = await cryptoApi.signWalletKycAuth({
      accountPriv: merchantPair1.priv,
      accountPub: merchantPair1.pub,
    });

    const checkResp1 = succeedOrThrow(
      await exchangeApi.checkKycStatus({
        accountPub: merchantPair1.pub,
        accountSig: sigResp.sig,
        paytoHash: kycPaytoHash,
      }),
    );
    console.log(j2s(checkResp1));
  }
}

runExchangeMerchantKycAuthTest.suites = ["wallet"];
