--
-- 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/>
--

-- @file merchant-0022.sql
-- @brief Add phone number for merchant instances
-- @author Christian Grothoff
--
-- @brief Create table to store donau related information
-- @author Bohdan Potuzhnyi
-- @author Vlada Svirsh


BEGIN;

-- Check patch versioning is in place.
SELECT _v.register_patch('merchant-0022', NULL, NULL);

SET search_path TO merchant;

ALTER TABLE merchant_used_tokens
  DROP COLUMN merchant_serial;

ALTER TABLE merchant_instances
  ADD COLUMN phone_number TEXT DEFAULT NULL,
  ADD COLUMN phone_validated BOOL NOT NULL DEFAULT FALSE,
  ADD COLUMN email_validated BOOL NOT NULL DEFAULT FALSE,
  ADD COLUMN validation_needed BOOL NOT NULL DEFAULT FALSE,
  ADD COLUMN validation_expiration INT8 NOT NULL DEFAULT 0,
  DROP COLUMN user_type;

COMMENT ON COLUMN merchant_instances.phone_number
  IS 'Phone number of the merchant to use for password reset (and to contact the merchant as the backend operator); optional if 2-FA is not used and/or for legacy instances';
COMMENT ON COLUMN merchant_instances.phone_validated
  IS 'TRUE if the merchant backend validated the phone number';
COMMENT ON COLUMN merchant_instances.email_validated
  IS 'TRUE if the merchant backend validated the e-mail address';
COMMENT ON COLUMN merchant_instances.validation_needed
  IS 'TRUE if this is a self-provisioned instance that still needs the recovery addresses to be validated';
COMMENT ON COLUMN merchant_instances.validation_expiration
  IS 'Time when the instance should be garbage collected if the recovery addresses remain unvalidated';

CREATE INDEX merchant_instances_validation_expiration_gc
  ON merchant_instances
  (validation_expiration ASC)
  WHERE validation_needed;


-- Create triggers to set confirmed/expected status on UPDATE.
CREATE FUNCTION merchant_expected_transfers_update_trigger()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
  UPDATE merchant_transfers
     SET expected = TRUE
   WHERE wtid = NEW.wtid
     AND exchange_url = NEW.exchange_url
     AND credit_amount = NEW.expected_credit_amount
     AND NOT expected;
  NEW.confirmed = NEW.confirmed OR FOUND;
  RETURN NEW;
END $$;
COMMENT ON FUNCTION merchant_expected_transfers_update_trigger
  IS 'Sets "confirmed" to TRUE for the new record if the expected transfer was already confirmed, and updates the already confirmed transfer to "expected"';

-- Whenever an expected transfer is added, check if it was already confirmed
CREATE TRIGGER merchant_expected_transfers_on_update
  BEFORE UPDATE
    ON merchant.merchant_expected_transfers
  FOR EACH ROW EXECUTE FUNCTION merchant_expected_transfers_update_trigger();


CREATE TABLE IF NOT EXISTS merchant_donau_keys
(donau_keys_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
  ,donau_url TEXT PRIMARY KEY
  ,keys_json TEXT NOT NULL
  ,first_retry INT8 NOT NULL DEFAULT (0)
);

COMMENT ON TABLE merchant_donau_keys
  IS 'Here we store the cached /keys response from Donau in JSON format';
COMMENT ON COLUMN merchant_donau_keys.donau_keys_serial
  IS 'Unique serial identifier for each cached key entry';
COMMENT ON COLUMN merchant_donau_keys.donau_url
  IS 'Base URL of Donau associated with these keys';
COMMENT ON COLUMN merchant_donau_keys.keys_json
  IS 'JSON string of the /keys as generated by Donau';
COMMENT ON COLUMN merchant_donau_keys.first_retry
  IS 'Absolute time when this merchant may retry to fetch the keys from this donau at the earliest';

CREATE TABLE IF NOT EXISTS merchant_donau_instances
(donau_instances_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
  ,donau_url TEXT NOT NULL
  ,charity_name TEXT NOT NULL
  ,merchant_instance_serial INT8 NOT NULL
   REFERENCES merchant_instances (merchant_serial) ON DELETE CASCADE
  ,charity_id BIGINT NOT NULL
  ,charity_max_per_year taler_amount_currency NOT NULL
  ,charity_receipts_to_date taler_amount_currency NOT NULL
  ,current_year INT8 NOT NULL
);

COMMENT ON TABLE merchant_donau_instances
  IS 'Here we store information about individual Donau instances, including details about associated charities and donation limits';
COMMENT ON COLUMN merchant_donau_instances.donau_instances_serial
  IS 'Unique serial identifier for each Donau instance';
COMMENT ON COLUMN merchant_donau_instances.donau_url
  IS 'The URL associated with the Donau system for this instance';
COMMENT ON COLUMN merchant_donau_instances.merchant_instance_serial
  IS 'The serial from merchant_instances whose public key is public key of the charity organization';
COMMENT ON COLUMN merchant_donau_instances.charity_id
  IS 'The unique identifier for the charity organization linked to this Donau instance';
COMMENT ON COLUMN merchant_donau_instances.charity_max_per_year
  IS 'Maximum allowable donation amount per year for the charity associated with this instance, stored in taler_amount_currency';
COMMENT ON COLUMN merchant_donau_instances.charity_receipts_to_date
  IS 'The total amount of donations received to date for this instance, stored in taler_amount_currency';
COMMENT ON COLUMN merchant_donau_instances.current_year
  IS 'The current year for tracking donations for this instance, stored as an 8-byte integer';

CREATE TABLE IF NOT EXISTS merchant_order_token_blinded_sigs
  (order_token_bs_serial BIGINT GENERATED BY DEFAULT AS IDENTITY 
  ,order_serial BIGINT NOT NULL
   REFERENCES merchant_contract_terms (order_serial) ON DELETE CASCADE
  ,token_index INT4 NOT NULL
  ,token_blinded_signature BYTEA NOT NULL
  ,token_hash BYTEA NOT NULL CHECK (LENGTH(token_hash)=64)
  ,PRIMARY KEY (order_serial, token_index)
);

COMMENT ON TABLE merchant_order_token_blinded_sigs
  IS 'Table linking merchant orders with Donau BUDIS information';
COMMENT ON COLUMN merchant_order_token_blinded_sigs.token_index
  IS 'offset of the given signature in the output token array';
COMMENT ON COLUMN merchant_order_token_blinded_sigs.order_token_bs_serial
  IS 'Unique serial identifier for token order linkage';
COMMENT ON COLUMN merchant_order_token_blinded_sigs.order_serial
  IS 'Foreign key linking to the corresponding merchant order';
COMMENT ON COLUMN merchant_order_token_blinded_sigs.token_blinded_signature
  IS 'Blinded signature of the token associated with the order';
COMMENT ON COLUMN merchant_order_token_blinded_sigs.token_hash
  IS 'Hash of the token';


COMMIT;
