--
-- 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 PROCEDURE IF EXISTS merchant_do_gc;
CREATE PROCEDURE merchant_do_gc(in_now INT8)
LANGUAGE plpgsql
AS $$
DECLARE
  rec RECORD;
  s TEXT;
BEGIN
  -- Per-instance GC: loop over all instances and run the
  -- per-instance GC helpers + targeted DELETEs in each schema.
  FOR rec IN SELECT merchant_serial FROM merchant.merchant_instances
  LOOP
    s := 'merchant_instance_' || rec.merchant_serial::TEXT;
    BEGIN
      EXECUTE format('SET LOCAL search_path TO %I, merchant', s);
      EXECUTE format('CALL %I.merchant_statistic_amount_gc()', s);
      EXECUTE format('CALL %I.merchant_statistic_bucket_gc()', s);
      EXECUTE format('CALL %I.merchant_statistic_counter_gc()', s);
      EXECUTE format('DELETE FROM %I.merchant_unclaim_signatures'
                     ' WHERE expiration_time < $1', s) USING in_now;
    EXCEPTION
      WHEN undefined_table THEN
        NULL;
      WHEN undefined_function THEN
        NULL;
      WHEN OTHERS THEN
        -- Do not abandon garbage collection for all remaining instances
        -- (and the global tables) just because one instance failed.
        RAISE WARNING 'Garbage collection failed for %: % (%)',
          s, SQLERRM, SQLSTATE;
    END;
    COMMIT;
  END LOOP;
  DELETE FROM merchant.tan_challenges
    WHERE expiration_date < $1;
  -- Restore the global search_path so subsequent statements on this
  -- session don't leak into the last visited instance schema.
  SET LOCAL search_path TO merchant;
END $$;
COMMENT ON PROCEDURE merchant_do_gc
  IS 'Calls per-instance garbage collection subroutines across every instance.'
     ' For each'
     ' instance runs merchant_statistic_*_gc and DELETEs expired tan_challenges'
     ' / merchant_unclaim_signatures.';
-- Note: deliberately no COMMIT here.  gen-procedures.sh wraps the entire
-- concatenation of sql_global_procedures in a single BEGIN ... COMMIT;
-- a COMMIT in this file would close that transaction early, so everything
-- appended after this file would be installed outside of it (and the
-- generator's own trailing COMMIT would warn 'there is no transaction in
-- progress').  The COMMIT inside the procedure body above is a plpgsql
-- transaction-control statement and is unrelated.
