--
-- 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/>
--
-- @author: Christian Grothoff

DROP FUNCTION IF EXISTS exchange_do_lookup_kyc_requirement_by_row;

CREATE FUNCTION exchange_do_lookup_kyc_requirement_by_row(
  IN in_h_normalized_payto BYTEA,
  IN in_account_pub BYTEA,
  OUT out_access_token BYTEA, -- NULL if 'out_not_found'
  OUT out_jrules JSONB, -- NULL allowed
  OUT out_is_wallet BOOLEAN, -- NULL allowed
  OUT out_not_found BOOLEAN,
  OUT out_rule_gen INT8, -- NULL allowed
  OUT out_aml_review BOOLEAN, -- NULL allowed
  OUT out_kyc_required BOOLEAN)
LANGUAGE plpgsql
AS $$
DECLARE
  my_wtrec RECORD;
  my_lorec RECORD;
  my_ok BOOL;
BEGIN

-- Find the access token and the current account public key.
SELECT access_token
      ,target_pub
      ,is_wallet
  INTO my_wtrec
  FROM kyc_targets
 WHERE h_normalized_payto=in_h_normalized_payto;

IF NOT FOUND
THEN
  -- RAISE WARNING 'kyc_target % not found', in_h_normalized_payto;
  -- Given that we don't recognize the normalized payto, there is no
  -- chance that we can match the incoming public key against anything,
  -- so this is a 404-case.
  out_not_found = TRUE;
  out_kyc_required = FALSE;
  RETURN;
END IF;

-- It is definitively OK if we were given a public key AND it matches
my_ok = COALESCE(my_wtrec.target_pub = in_account_pub, FALSE);

IF (NOT my_ok)
THEN
  -- We were given an in_account_pub, but it did not match the
  -- target pub.
  -- Try to see if the in_account_pub appears in ANY reserve_in
  -- or kyc_auths_in for this account instead.
  PERFORM
     FROM reserves_in ri
     JOIN wire_targets wt
       ON (ri.wire_source_h_payto = wt.wire_target_h_payto)
    WHERE ri.reserve_pub=in_account_pub
      AND wt.h_normalized_payto=in_h_normalized_payto;
  IF FOUND
  THEN
    my_wtrec.target_pub = in_account_pub;
    my_ok = TRUE;
  ELSE
    PERFORM
       FROM kycauths_in ki
       JOIN wire_targets wt
         ON (ki.wire_source_h_payto = wt.wire_target_h_payto)
      WHERE ki.account_pub=in_account_pub
        AND wt.h_normalized_payto=in_h_normalized_payto;
    IF FOUND
    THEN
      my_wtrec.target_pub = in_account_pub;
      my_ok = TRUE;
    END IF;
  END IF;
END IF;

IF (NOT my_ok)
THEN
  -- RAISE WARNING 'No match';
  -- We failed to find a matching public key for in_account_pub, and
  -- either the client provided a specific one to match OR
  -- we could not return any one that could even work, which means
  -- we are lacking the KYC auth or any even a triggered requirement.
  out_not_found = TRUE;
  out_kyc_required = FALSE;
  RETURN;
END IF;

-- We have found "something", which may or may not match the input
-- public key (if there was one), but at least some KYC requirement
-- exists.
out_not_found = FALSE;

out_is_wallet = my_wtrec.is_wallet;
out_access_token = my_wtrec.access_token;

-- Check if there are active measures for the account.
PERFORM
  FROM legitimization_measures
 WHERE access_token=out_access_token
   AND NOT is_finished
 LIMIT 1;

out_kyc_required = FOUND;

-- Get currently applicable rules.
-- Only one should ever be active per account.
SELECT jnew_rules
      ,to_investigate
      ,outcome_serial_id
  INTO my_lorec
  FROM legitimization_outcomes
 WHERE h_payto=in_h_normalized_payto
   AND is_active;

IF FOUND
THEN
  out_jrules=my_lorec.jnew_rules;
  out_aml_review=my_lorec.to_investigate;
  out_rule_gen=my_lorec.outcome_serial_id;
END IF;

END $$;
