--
-- This file is part of TALER
-- Copyright (C) 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_do_solve_mfa_challenge;
CREATE FUNCTION merchant_do_solve_mfa_challenge (
  IN in_challenge_id INT8,
  IN in_h_body BYTEA,
  IN in_solution TEXT,
  IN in_now INT8,
  OUT out_solved BOOLEAN,
  OUT out_retry_counter INT4
)
LANGUAGE plpgsql
AS $$
DECLARE
  my_confirmation_date INT8;
DECLARE
  my_rec RECORD;
BEGIN

  -- Check if challenge exists and matches
  SELECT
    tc.confirmation_date
   ,tc.retry_counter
   ,(tc.code = in_solution) AS solved
  INTO
    my_rec
  FROM tan_challenges tc
  WHERE tc.challenge_id = in_challenge_id
    AND tc.h_body = in_h_body
    AND tc.expiration_date > in_now;

  IF NOT FOUND
  THEN
    out_solved = FALSE;
    RETURN;
  END IF;

  my_confirmation_date = my_rec.confirmation_date;
  out_retry_counter = my_rec.retry_counter;
  out_solved = my_rec.solved;

  -- Check if already solved before
  IF my_confirmation_date IS NOT NULL
  THEN
    out_solved = TRUE;
    RETURN;
  END IF;

  IF (0 = out_retry_counter)
  THEN
    out_solved = FALSE;
    RETURN;
  END IF;

  IF out_solved
  THEN
    -- Newly solved, update DB!
    my_confirmation_date = in_now;
    UPDATE tan_challenges
       SET confirmation_date = my_confirmation_date
     WHERE challenge_id = in_challenge_id;
  ELSE
    -- Failed to solve, decrement retry counter
    out_retry_counter = out_retry_counter - 1;
    UPDATE tan_challenges
       SET retry_counter = out_retry_counter
     WHERE challenge_id = in_challenge_id;
  END IF;
END;
$$;
