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

-- @file merchant-0013.sql
-- @brief Creating trigger for the category change webhook
-- @author Bohdan Potuzhnyi
-- @author Vlada Svirsh


BEGIN;

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

SET search_path TO merchant;

-- Slug was incorrectly set to be globally unique, is only
-- unique per instance! Drop the constraint and add correct one.
ALTER TABLE merchant_token_families
  DROP CONSTRAINT merchant_token_families_slug_key,
  ADD UNIQUE (merchant_serial,slug),
  DROP COLUMN rounding, -- replaced by validity_granularity
  ADD validity_granularity INT8 NOT NULL CHECK
    (validity_granularity IN (60000000,3600000000,86400000000,604800000000,2592000000000,7776000000000,31536000000000))
    DEFAULT (2592000000000), -- 30 days
  ADD start_offset INT8 NOT NULL DEFAULT (0),
  ADD cipher_choice TEXT NOT NULL DEFAULT ('rsa(2048)'),
  ADD extra_data TEXT DEFAULT NULL;

COMMENT ON COLUMN merchant_token_families.validity_granularity
  IS 'To compute key lifetimes, we first round the payment deadline down to a multiple of this time; supported values are one minute, one hour, a day, a week, 30 days, 90 days or a year (indicatited using 365 days); adding the start_offset gets the start validity time; adding the duration to get the signature_valid_until value for the key';
COMMENT ON COLUMN merchant_token_families.start_offset
  IS 'This allows shifting the validity period of signatures to start a bit before the time rounded to the precision. For example, Swiss vignettes are valid for 14 months, from December of year X to January of year X+2. This can be achieve by setting a start_offset of 30 days, and a duration of 14 months and a precision of 1 year. The value given is in microseconds (but will be rounded to seconds).';
COMMENT ON COLUMN merchant_token_families.cipher_choice
  IS 'Specifies the type of cipher that should be used for this token family. Currently supported values are "cs" and "rsa($LEN)" where $LEN is the key length in bits.';
COMMENT ON COLUMN merchant_token_families.extra_data
  IS 'JSON field with family-specific meta data, such as the trusted_domains for subscriptions or expected_domains for discount tokens';


-- Keep proper periods for token keys.
ALTER TABLE merchant_token_family_keys
  DROP valid_before,
  DROP valid_after,
  ADD signature_validity_start INT8 NOT NULL DEFAULT (0),
  ADD signature_validity_end INT8 NOT NULL DEFAULT (0),
  ADD private_key_deleted_at INT8 NOT NULL DEFAULT (0),
  ADD private_key_created_at INT8 NOT NULL DEFAULT (0);

COMMENT ON COLUMN merchant_token_family_keys.signature_validity_start
  IS 'Specifies the earliest time at which tokens signed with this key can be considered valid. Allows tokens to be issued way in advance of their validity.';
COMMENT ON COLUMN merchant_token_family_keys.signature_validity_end
  IS 'Specifies when the tokens signed by this key expire.';
COMMENT ON COLUMN merchant_token_family_keys.private_key_deleted_at
  IS 'Specifies how long tokens signed by this key can be created, that is the point at which the private key may be deleted. Computed by determining when the *next* validity period starts, or when the overall token family validity period ends.';
COMMENT ON COLUMN merchant_token_family_keys.private_key_created_at
  IS 'Specifies when the private key was created. Not terribly useful, mostly for debugging.';

-- Function to replace placeholders in a string with a given value
CREATE FUNCTION replace_placeholder(
  template TEXT,
  key TEXT,
  value TEXT
) RETURNS TEXT AS $$
BEGIN
  RETURN regexp_replace(
    template,
    '{{\s*' || key || '\s*}}', -- Match the key with optional spaces
    value,
    'g' -- Global replacement
  );
END;
$$ LANGUAGE plpgsql;

CREATE FUNCTION handle_inventory_changes()
  RETURNS TRIGGER AS $$
BEGIN
  -- This is just a dummy function, the actual
  -- implementation lives in pg_do_handle_inventory_changes.sql
  -- and is loaded later!
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE FUNCTION handle_category_changes()
  RETURNS TRIGGER AS $$
BEGIN
  -- This is just a dummy function, the actual
  -- implementation lives in pg_do_handle_category_changes.sql
  -- and is loaded later!
  RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Trigger to invoke the trigger function
CREATE TRIGGER trigger_category_changes
AFTER INSERT OR UPDATE OR DELETE
ON merchant_categories
FOR EACH ROW
EXECUTE FUNCTION handle_category_changes();

-- Trigger to invoke the trigger function
CREATE TRIGGER trigger_inventory_changes
  AFTER INSERT OR UPDATE OR DELETE
  ON merchant_inventory
  FOR EACH ROW
EXECUTE FUNCTION handle_inventory_changes();


COMMIT;
