--
-- This file is part of TALER
-- Copyright (C) 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/>
--

DROP FUNCTION IF EXISTS merchant_do_insert_transfer;
CREATE FUNCTION merchant_do_insert_transfer (
  IN in_instance_id TEXT,
  IN in_exchange_url TEXT,
  IN in_wtid BYTEA,
  IN in_credit_amount taler_amount_currency,
  IN in_credited_account_payto TEXT,
  IN in_bank_serial_id INT8, -- can be NULL if unknown
  IN in_execution_time INT8,
  OUT out_no_instance BOOL,
  OUT out_no_account BOOL,
  OUT out_conflict BOOL)
LANGUAGE plpgsql
AS $$
DECLARE
  my_merchant_id INT8;
  my_account_serial INT8;
  my_record RECORD;
  my_bank_serial_id INT8;
  my_credit_amount taler_amount_currency;
BEGIN

out_conflict=FALSE;

-- Which instance are we using?
SELECT merchant_serial
  INTO my_merchant_id
  FROM merchant_instances
 WHERE merchant_id=in_instance_id;
IF NOT FOUND
THEN
  out_no_instance=TRUE;
  out_no_account=TRUE; -- also true...
  RETURN;
END IF;
out_no_instance=FALSE;

SELECT account_serial
  INTO my_account_serial
  FROM merchant_accounts
 WHERE REGEXP_REPLACE(payto_uri,
                      '\\?.*','')
      =REGEXP_REPLACE(in_credited_account_payto,
                      '\\?.*','')
   AND merchant_serial=my_merchant_id;
IF NOT FOUND
THEN
  out_no_account=TRUE;
  RETURN;
END IF;
out_no_account=FALSE;

SELECT bank_serial_id
      ,credit_amount
  INTO my_record
  FROM merchant_transfers
 WHERE wtid=in_wtid
   AND account_serial=my_account_serial
   AND exchange_url=in_exchange_url;
IF NOT FOUND
THEN
  INSERT INTO merchant_transfers
    (exchange_url
    ,wtid
    ,credit_amount
    ,account_serial
    ,bank_serial_id
    ,execution_time
    ) VALUES
    (in_exchange_url
    ,in_wtid
    ,in_credit_amount
    ,my_account_serial
    ,in_bank_serial_id
    ,in_execution_time);
  -- Do notify on TALER_DBEVENT_MERCHANT_WIRE_TRANSFER_CONFIRMED
  NOTIFY XJ5N652FA4TBS2WXGY3S1FMPMQYTD8KAZA9B7HW9JWJ4PZ2DB852G;
  RETURN;
END IF;

my_bank_serial_id = my_record.bank_serial_id;
my_credit_amount = my_record.credit_amount;

IF ( (in_credit_amount.val  != my_credit_amount.val)  OR
     (in_credit_amount.frac != my_credit_amount.frac) OR
     (in_credit_amount.curr != my_credit_amount.curr) )
THEN
  out_conflict = TRUE; -- amounts differ, not OK!
  RETURN;
END IF;

IF ( (my_bank_serial_id IS NULL) AND
     (in_bank_serial_id IS NOT NULL) )
THEN
  -- We learned the bank_bank_serial_id, update that
  UPDATE merchant_transfers
     SET bank_serial_id=in_bank_serial_id
   WHERE wtid=in_wtid
     AND account_serial=my_account_serial
     AND exchange_url=in_exchange_url;
  RETURN;
END IF;

-- idempotent request, success.

END $$;
