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

CREATE OR REPLACE FUNCTION challenger_do_validate_and_solve_pin (
  IN in_nonce BYTEA,
  IN in_new_pin INT4,
  OUT out_not_found BOOLEAN,
  OUT out_exhausted BOOLEAN,
  OUT out_no_challenge BOOLEAN,
  OUT out_solved BOOLEAN,
  OUT out_state TEXT,
  OUT out_address_attempts_left INT4,
  OUT out_auth_attempts_left INT4,
  OUT out_pin_transmissions_left INT4,
  OUT out_client_redirect_uri TEXT)
LANGUAGE plpgsql
AS $$
DECLARE
  my_status RECORD;
BEGIN

SELECT auth_attempts_left
      ,address_attempts_left
      ,pin_transmissions_left
      ,last_pin
      ,client_redirect_uri
      ,client_state
  INTO my_status
  FROM validations
 WHERE nonce=in_nonce;

IF NOT FOUND
THEN
  out_not_found=TRUE;
  out_no_challenge=TRUE;
  out_exhausted=FALSE;
  out_solved=FALSE;
  out_address_attempts_left=0;
  out_auth_attempts_left=0;
  out_pin_transmissions_left=0;
  out_client_redirect_uri=NULL;
  out_state=NULL;
  RETURN;
END IF;
out_not_found=FALSE;
out_address_attempts_left=my_status.address_attempts_left;
out_pin_transmissions_left=my_status.pin_transmissions_left;
out_client_redirect_uri=my_status.client_redirect_uri;
out_state=my_status.client_state;

IF (my_status.last_pin IS NULL)
THEN
  out_solved=FALSE;
  out_exhausted=FALSE;
  out_auth_attempts_left=0;
  out_no_challenge=TRUE;
  RETURN;
END IF;
out_no_challenge=FALSE;

IF (0 > my_status.auth_attempts_left)
THEN
  out_solved=TRUE;
  out_exhausted=TRUE;
  out_auth_attempts_left=0;
  RETURN;
END IF;

IF (0 = my_status.auth_attempts_left)
THEN
  out_solved=FALSE;
  out_exhausted=TRUE;
  out_auth_attempts_left=0;
  RETURN;
END IF;
out_exhausted=FALSE;
out_solved = (my_status.last_pin = in_new_pin);

IF NOT out_solved
THEN
  out_auth_attempts_left=my_status.auth_attempts_left-1;
ELSE
  out_auth_attempts_left=-1; -- solved: no more attempts
END IF;

UPDATE validations
 SET auth_attempts_left=out_auth_attempts_left
 WHERE nonce=$1;

RETURN;

END $$;
