import{sql as _}from"drizzle-orm";import{logger as y}from"../../../../../tools/notifiers/logger.js";import{buildRbacFilterRaw as d}from"../utils/build-rbac-filter.js";class A{#e;constructor(i){this.#e=i}async getCatalogFilters({entitiesTypes:i=[],emptyFilters:t=[],rbacTeams:a,excludedTypes:s,excludedEntities:c}){try{const e={},u=t.filter(l=>l.startsWith("metadata.")),f=t.includes("domains")||t.includes("owners"),N=this.#t({entitiesTypes:i,rbacTeams:a,excludedTypes:s,excludedEntities:c,withRelations:f}),r=[];if(t.includes("type")&&r.push(`
          SELECT 'type' AS filter_name, type AS value, COUNT(*) AS count
          FROM filtered_entities
          WHERE type IS NOT NULL
          GROUP BY type
        `),t.includes("tags")&&r.push(`
          SELECT 'tags' AS filter_name, tag.value AS value, COUNT(DISTINCT fe.key) AS count
          FROM filtered_entities fe, json_each(COALESCE(fe.tags, json_array())) AS tag
          WHERE fe.tags IS NOT NULL
            AND fe.tags != ''
            AND tag.value IS NOT NULL
            AND tag.value != ''
          GROUP BY tag.value
        `),t.includes("domains")&&r.push(`
          SELECT 'domains' AS filter_name, cr.source_key AS value, COUNT(DISTINCT fe.key) AS count
          FROM combined_relations cr
          INNER JOIN filtered_entities fe ON fe.key = cr.target_key
          INNER JOIN combined_entities ce ON ce.key = cr.source_key
          WHERE ce.type = 'domain'
            AND cr.source_to_target_relation = 'hasParts'
          GROUP BY cr.source_key
        `),t.includes("owners")&&r.push(`
          SELECT 'owners' AS filter_name, owner_key AS value, COUNT(DISTINCT entity_key) AS count
          FROM (
            SELECT
              fe.key AS entity_key,
              CASE
                WHEN fe.key = cr.target_key AND cr.source_to_target_relation = 'owns'
                THEN cr.source_key
                WHEN fe.key = cr.source_key AND cr.source_to_target_relation = 'ownedBy'
                THEN cr.target_key
              END AS owner_key
            FROM combined_relations cr
            INNER JOIN filtered_entities fe ON (
              (cr.target_key = fe.key AND cr.source_to_target_relation = 'owns') OR
              (cr.source_key = fe.key AND cr.source_to_target_relation = 'ownedBy')
            )
          ) AS entity_owners
          INNER JOIN combined_entities ce ON ce.key = owner_key
          WHERE owner_key IS NOT NULL
          GROUP BY owner_key
        `),r.length>0){const l=await this.#e.client.run(_.raw(`
            ${N}
            ${r.join(" UNION ALL ")}
          `));for(const o of l.rows??[]){const n=o.filter_name,E=o.value,S=Number(o.count)||0;E&&(e[n]||(e[n]=[]),e[n].push({value:E,count:S}))}}if(u.length>0){const l=await this.#e.client.run(_`
            ${_.raw(N)}
            ${_.join(u.map(o=>{const n=A.#n(o);return _`
                  SELECT
                    ${o} AS filter_name,
                    json_extract(metadata, ${n}) AS value,
                    COUNT(*) AS count
                  FROM filtered_entities
                  WHERE metadata IS NOT NULL
                    AND metadata != ''
                    AND json_extract(metadata, ${n}) IS NOT NULL
                    AND json_extract(metadata, ${n}) != ''
                  GROUP BY 2
                `}),_`
UNION ALL
`)}
          `);for(const o of l.rows??[]){const n=o.filter_name,E=o.value,S=Number(o.count)||0;E&&(e[n]||(e[n]=[]),e[n].push({value:E,count:S}))}}return e}catch(e){return y.error("Error fetching catalog filters: "+e.message),{}}}#t({entitiesTypes:i,rbacTeams:t,excludedTypes:a,excludedEntities:s,withRelations:c=!1}){const e="entity",u="entityAttributes",f=d(t,u),N=this.#i(a,s),r=[`${e}.is_current = 1`,`${e}.is_deleted = 0`];f&&r.push(f),N&&r.push(N.replace(/ENTITY_ALIAS/g,e));const l=i.length?`SELECT * FROM combined_entities WHERE type IN (${i.map(n=>`'${n.replace(/'/g,"''")}'`).join(",")})`:"SELECT * FROM combined_entities",o=c?`,
      combined_relations AS (
        SELECT source_key, target_key, source_to_target_relation
        FROM entities_relations
        WHERE COALESCE(is_deleted, 0) = 0
      )`:"";return`
      WITH
      combined_entities AS (
        SELECT
          ${e}.key,
          ${e}.type,
          ${e}.tags,
          ${e}.metadata
        FROM entities ${e}
        LEFT JOIN entities_attributes ${u} ON ${u}.entity_key = ${e}.key
        WHERE ${r.join(" AND ")}
      ),
      filtered_entities AS (
        ${l}
      )
      ${o}
    `}static#n(i){return`$.${i.substring(9).replace(/[^a-zA-Z0-9._-]/g,"")}`}#i(i,t){const a=[];if(i&&i.length>0){const s=i.map(c=>`'${c.replace(/'/g,"''")}'`).join(", ");a.push(`ENTITY_ALIAS.type NOT IN (${s})`)}if(t&&t.length>0){const s=t.map(c=>`'${c.replace(/'/g,"''")}'`).join(", ");a.push(`ENTITY_ALIAS.key NOT IN (${s})`)}return a.length>0?`(${a.join(" AND ")})`:null}}export{A as FiltersRepository};
