--
-- Status tracking: view_generated_at on sources and stacks
-- Cleared by triggers when definitions change; set by API when views are generated.
--

SET search_path TO dataflow, public;

-- Add view_generated_at columns
ALTER TABLE dataflow.sources ADD COLUMN IF NOT EXISTS view_generated_at TIMESTAMPTZ;
ALTER TABLE dataflow.stacks  ADD COLUMN IF NOT EXISTS view_generated_at TIMESTAMPTZ;

------------------------------------------------------
-- Trigger: clear source view_generated_at when rules change
------------------------------------------------------
CREATE OR REPLACE FUNCTION dataflow.rules_changed()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE dataflow.sources SET view_generated_at = NULL
    WHERE name = COALESCE(NEW.source_name, OLD.source_name);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_rules_changed ON dataflow.rules;
CREATE TRIGGER trg_rules_changed
AFTER INSERT OR UPDATE OR DELETE ON dataflow.rules
FOR EACH ROW EXECUTE FUNCTION dataflow.rules_changed();

------------------------------------------------------
-- Trigger: clear source view_generated_at when mappings change
------------------------------------------------------
CREATE OR REPLACE FUNCTION dataflow.mappings_changed()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE dataflow.sources SET view_generated_at = NULL
    WHERE name = COALESCE(NEW.source_name, OLD.source_name);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_mappings_changed ON dataflow.mappings;
CREATE TRIGGER trg_mappings_changed
AFTER INSERT OR UPDATE OR DELETE ON dataflow.mappings
FOR EACH ROW EXECUTE FUNCTION dataflow.mappings_changed();

------------------------------------------------------
-- Trigger: clear stack view_generated_at when sources change
------------------------------------------------------
CREATE OR REPLACE FUNCTION dataflow.stack_sources_changed()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE dataflow.stacks SET view_generated_at = NULL
    WHERE name = COALESCE(NEW.stack_name, OLD.stack_name);
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_stack_sources_changed ON dataflow.stack_sources;
CREATE TRIGGER trg_stack_sources_changed
AFTER INSERT OR UPDATE OR DELETE ON dataflow.stack_sources
FOR EACH ROW EXECUTE FUNCTION dataflow.stack_sources_changed();

------------------------------------------------------
-- Function: get_status
-- Returns sources and stacks whose view is stale (null or never generated)
------------------------------------------------------
CREATE OR REPLACE FUNCTION get_status()
RETURNS JSON AS $$
DECLARE
    v_sources JSON;
    v_stacks  JSON;
BEGIN
    SELECT COALESCE(json_agg(json_build_object('name', name, 'view_generated_at', view_generated_at) ORDER BY name), '[]'::json)
    INTO v_sources
    FROM dataflow.sources
    WHERE view_generated_at IS NULL;

    SELECT COALESCE(json_agg(json_build_object('name', name, 'view_generated_at', view_generated_at) ORDER BY name), '[]'::json)
    INTO v_stacks
    FROM dataflow.stacks
    WHERE view_generated_at IS NULL;

    RETURN json_build_object('stale_sources', v_sources, 'stale_stacks', v_stacks);
END;
$$ LANGUAGE plpgsql STABLE;
