--
-- 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_challenge_set_address_and_pin (
  IN in_nonce BYTEA,
  IN in_address TEXT,
  IN in_next_tx_time INT8,
  IN in_now INT8,
  IN in_tan INT4,
  OUT out_not_found BOOLEAN,
  OUT out_last_tx_time INT8,
  OUT out_last_pin INT4,
  OUT out_state TEXT,
  OUT out_pin_transmit BOOLEAN,
  OUT out_auth_attempts_left INT4,
  OUT out_client_redirect_uri TEXT,
  OUT out_address_refused BOOLEAN,
  OUT out_solved BOOLEAN)
LANGUAGE plpgsql
AS $$
DECLARE
  my_status RECORD;
  my_do_update BOOL;
BEGIN

my_do_update = FALSE;

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

IF NOT FOUND
THEN
  out_not_found=TRUE;
  out_last_tx_time=0;
  out_last_pin=0;
  out_pin_transmit=FALSE;
  out_auth_attempts_left=0;
  out_client_redirect_uri=NULL;
  out_address_refused=TRUE;
  out_solved=FALSE;
  out_state=NULL;
  RETURN;
END IF;
out_not_found=FALSE;
out_last_tx_time=my_status.last_tx_time;
out_last_pin=my_status.last_pin;
out_pin_transmit=FALSE;
out_auth_attempts_left=my_status.auth_attempts_left;
out_state=my_status.client_state;
out_client_redirect_uri=my_status.client_redirect_uri;

IF ( 0 > my_status.auth_attempts_left ) -- this challenge is solved
THEN
  out_address_refused=TRUE;
  out_solved=TRUE;
  out_auth_attempts_left=0;
  RETURN;
END IF;
out_solved=FALSE;

IF ( (0 = my_status.address_attempts_left) AND
     (in_address != my_status.address) )
THEN
  out_address_refused=TRUE;
  out_last_pin=0;
  RETURN;
END IF;
out_address_refused=FALSE;

IF ( (my_status.address IS NULL) OR
     (in_address != my_status.address) )
THEN
  -- we are changing the address, update counters
  my_status.address_attempts_left = my_status.address_attempts_left - 1;
  my_status.address = in_address;
  my_status.pin_transmissions_left = 3;
  my_status.last_tx_time = 0;
  my_do_update=TRUE;
END IF;

IF ( (my_status.pin_transmissions_left > 0) AND
     (my_status.last_tx_time <= in_next_tx_time) )
THEN
  -- we are changing the PIN, update counters
  my_status.pin_transmissions_left = my_status.pin_transmissions_left - 1;
  my_status.last_pin = in_tan;
  my_status.auth_attempts_left = 3;
  my_status.last_tx_time = in_now;
  out_auth_attempts_left = 3;
  out_pin_transmit=TRUE;
  out_last_pin = in_tan;
  out_last_tx_time = in_now;
  my_do_update=TRUE;
END IF;

IF my_do_update
THEN
  UPDATE validations SET
    address=my_status.address
   ,address_attempts_left=my_status.address_attempts_left
   ,pin_transmissions_left=my_status.pin_transmissions_left
   ,last_tx_time=my_status.last_tx_time
   ,last_pin=my_status.last_pin
   ,auth_attempts_left=my_status.auth_attempts_left
  WHERE nonce=$1;
END IF;

RETURN;

END $$;
