--
-- This file is part of TALER
-- Copyright (C) 2024, 2025 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_insert_deposit_to_transfer;
CREATE FUNCTION merchant_insert_deposit_to_transfer (
  IN in_deposit_serial INT8,
  IN in_coin_contribution taler_amount_currency,
  IN in_execution_time INT8,
  IN in_exchange_url TEXT,
  IN in_h_wire BYTEA,
  IN in_exchange_sig BYTEA,
  IN in_exchange_pub BYTEA,
  IN in_wtid BYTEA,
  OUT out_dummy BOOL)
LANGUAGE plpgsql
AS $$
DECLARE
  my_signkey_serial INT8;
  my_account_serial INT8;
  my_decose INT8;
  my_order_serial INT8;
  my_expected_credit_serial INT8;
  my_wire_pending_cleared BOOL;
  my_order_id TEXT;
BEGIN
  -- Just to return something (for now).
  out_dummy=FALSE;

-- Find exchange sign key
SELECT signkey_serial
  INTO my_signkey_serial
  FROM merchant_exchange_signing_keys
 WHERE exchange_pub=in_exchange_pub
   ORDER BY start_date DESC
   LIMIT 1;

IF NOT FOUND
THEN
  -- Maybe 'keys' is outdated, try again in 8 hours.
  UPDATE merchant_deposits
     SET settlement_last_ec=2029 -- MERCHANT_EXCHANGE_SIGN_PUB_UNKNOWN
        ,settlement_last_http_status=200
        ,settlement_last_detail=ENCODE(in_exchange_pub, 'hex')
        ,settlement_wtid=in_wtid
        ,settlement_retry_needed=TRUE
        ,settlement_retry_time=(EXTRACT(epoch FROM (CURRENT_TIME + interval '8 hours')) * 1000000)::INT8
   WHERE deposit_serial=in_deposit_serial;
  RETURN;
END IF;

-- Find deposit confirmation
SELECT deposit_confirmation_serial
  INTO my_decose
  FROM merchant_deposits
 WHERE deposit_serial=in_deposit_serial;

-- Find merchant account
SELECT account_serial
  INTO my_account_serial
  FROM merchant_deposit_confirmations mdc
  JOIN merchant_accounts ma
    USING (account_serial)
 WHERE mdc.deposit_confirmation_serial=my_decose
   AND ma.h_wire=in_h_wire;

IF NOT FOUND
THEN
  -- Merchant account referenced in exchange response is unknown to us.
  -- Remember fatal error and do not try again.
  UPDATE merchant_deposits
     SET settlement_last_ec=2558 -- MERCHANT_EXCHANGE_TRANSFERS_TARGET_ACCOUNT_UNKNOWN
        ,settlement_last_http_status=200
        ,settlement_last_detail=ENCODE(in_h_wire, 'hex')
        ,settlement_wtid=in_wtid
        ,settlement_retry_needed=FALSE
        ,settlement_coin_contribution=in_coin_contribution
        ,signkey_serial=my_signkey_serial
        ,settlement_exchange_sig=in_exchange_sig
   WHERE deposit_serial=in_deposit_serial;
  RETURN;
END IF;


-- Make sure wire transfer is expected.
SELECT expected_credit_serial
  INTO my_expected_credit_serial
  FROM merchant_expected_transfers
  WHERE wtid=in_wtid
    AND exchange_url=in_exchange_url
    AND account_serial=my_account_serial;

IF NOT FOUND
THEN
  INSERT INTO merchant_expected_transfers
    (exchange_url
    ,wtid
    ,account_serial
    ,expected_time)
   VALUES
    (in_exchange_url
    ,in_wtid
    ,my_account_serial
    ,in_execution_time)
   RETURNING expected_credit_serial
     INTO my_expected_credit_serial;
END IF;

-- Finally, update merchant_deposits so we do not try again.
UPDATE merchant_deposits
   SET settlement_last_ec=0
      ,settlement_last_http_status=200
      ,settlement_last_detail=NULL
      ,settlement_wtid=in_wtid
      ,settlement_retry_needed=FALSE
      ,settlement_coin_contribution=in_coin_contribution
      ,settlement_expected_credit_serial=my_expected_credit_serial
      ,signkey_serial=my_signkey_serial
      ,settlement_exchange_sig=in_exchange_sig
 WHERE deposit_serial=in_deposit_serial;

-- MERCHANT_WIRE_TRANSFER_EXPECTED
NOTIFY XR6849FMRD2AJFY1E2YY0GWA8GN0YT407Z66WHJB0SAKJWF8G2Q60;

END $$;
