--
-- This file is part of Anastasis
-- Copyright (C) 2026 Anastasis SARL
--
-- ANASTASIS 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.
--
-- ANASTASIS 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
-- ANASTASIS; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
--

DROP FUNCTION IF EXISTS anastasis_do_insert_recdoc_payment;
CREATE FUNCTION anastasis_do_insert_recdoc_payment (
  IN in_user_id BYTEA,
  IN in_post_counter INT4,
  IN in_amount taler_amount,
  IN in_payment_identifier BYTEA,
  IN in_creation_date INT8,
  IN in_transient_expiration INT8) -- lifetime given to an account created here
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN

-- anastasis_recdoc_payment references anastasis_user, so the account has to
-- exist first.  ON CONFLICT DO NOTHING settles the race between two first
-- uploads for the same account inside the statement; the SELECT ... FOR
-- UPDATE this replaces held no lock at all, because it ran in its own
-- autocommit transaction and released the row before the inserts.
INSERT INTO anastasis_user
  (user_id
  ,expiration_date)
  VALUES
  (in_user_id
  ,in_transient_expiration)
ON CONFLICT (user_id) DO NOTHING;

INSERT INTO anastasis_recdoc_payment
  (user_id
  ,post_counter
  ,amount
  ,payment_identifier
  ,creation_date)
  VALUES
  (in_user_id
  ,in_post_counter
  ,in_amount
  ,in_payment_identifier
  ,in_creation_date);

END $$;

COMMENT ON FUNCTION anastasis_do_insert_recdoc_payment
  IS 'Records the start of a payment for a recovery document upload, creating the account with a transient lifetime if it does not exist yet.  Atomic, so concurrent first uploads for one account cannot collide on the primary key.';
