-- Galaxy Object Hierarchy for OPC UA Server
-- Returns the parent-child hierarchy with both browse names (contained_name) and tag names.
-- Use browse_name for OPC UA browse tree display.
-- Use tag_name for runtime read/write tag references.
--
-- Derived from internal_automation_object_model_hierarchy_view2 logic:
--   - gobject: provides hierarchy (contained_by_gobject_id, area_gobject_id) and names
--   - template_definition: category_id filters to automation-relevant objects
--
-- Category IDs:
--   1  = $WinPlatform    (platform objects)
--   3  = $AppEngine       (application engines)
--   4  = $InTouchViewApp  (InTouch view apps)
--   10 = $UserDefined     (user-defined automation objects)
--   11 = $FieldReference  (field reference objects)
--   13 = $Area            (areas / folders)
--   17 = $DIObject        (DI objects)
--   24 = $DDESuiteLinkClient
--   26 = $OPCClient
--
-- template_chain (new): pipe-delimited list of template tag_names walking
-- gobject.derived_from_gobject_id from the instance upward. Index 0 is the
-- object's own immediate template, the last entry is the most ancestral
-- template before $Object. Mirrors the deployed_package_chain CTE pattern
-- in attributes.sql. Consumed by AlarmObjectFilter for template-based
-- alarm filtering with wildcard support.

;WITH template_chain AS (
    -- Start from each non-template deployed instance's own template
    SELECT
        g.gobject_id AS instance_gobject_id,
        t.gobject_id AS template_gobject_id,
        t.tag_name AS template_tag_name,
        t.derived_from_gobject_id,
        0 AS depth
    FROM gobject g
    INNER JOIN gobject t
        ON t.gobject_id = g.derived_from_gobject_id
    WHERE g.is_template = 0
        AND g.deployed_package_id <> 0
        AND g.derived_from_gobject_id <> 0
    UNION ALL
    -- Walk up the template derivation chain
    SELECT
        tc.instance_gobject_id,
        t.gobject_id,
        t.tag_name,
        t.derived_from_gobject_id,
        tc.depth + 1
    FROM template_chain tc
    INNER JOIN gobject t
        ON t.gobject_id = tc.derived_from_gobject_id
    WHERE tc.derived_from_gobject_id <> 0 AND tc.depth < 10
)
SELECT DISTINCT
    g.gobject_id,
    g.tag_name,
    g.contained_name,
    CASE WHEN g.contained_name IS NULL OR g.contained_name = ''
         THEN g.tag_name
         ELSE g.contained_name
    END AS browse_name,
    CASE WHEN g.contained_by_gobject_id = 0
         THEN g.area_gobject_id
         ELSE g.contained_by_gobject_id
    END AS parent_gobject_id,
    CASE WHEN td.category_id = 13
         THEN 1
         ELSE 0
    END AS is_area,
    td.category_id AS category_id,
    g.hosted_by_gobject_id AS hosted_by_gobject_id,
    ISNULL(
        STUFF((
            SELECT '|' + tc.template_tag_name
            FROM template_chain tc
            WHERE tc.instance_gobject_id = g.gobject_id
            ORDER BY tc.depth
            FOR XML PATH('')
        ), 1, 1, ''),
        ''
    ) AS template_chain
FROM gobject g
INNER JOIN template_definition td
    ON g.template_definition_id = td.template_definition_id
WHERE td.category_id IN (1, 3, 4, 10, 11, 13, 17, 24, 26)
    AND g.is_template = 0
    AND g.deployed_package_id <> 0
ORDER BY parent_gobject_id, g.tag_name;
