/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import e from"../../request.js";import{unique as t}from"../../core/arrayUtils.js";import o from"../../core/Error.js";import{getOrCreateMapValue as r}from"../../core/MapUtils.js";import{join as s}from"../../core/urlUtils.js";import n from"./ModelFileInfo.js";import a from"./ModelInfo.js";import{modelFormatFromFormatId as i,getFormatIdFormat as u,getFormatExtensions as l,formatIdFromModelFormat as f,getAssetMapTable as c}from"../support/infoFor3D.js";import{executeRawQueryJSON as d,executeQueryJSON as m}from"../../rest/query/executeQueryJSON.js";import p from"../../rest/support/Query.js";async function y(e,t,r,s){const n=e.infoFor3D;if(!n)throw new o("scenelayer:query-models-not-available","Model queries are not available without 3D object metadata",{layer:e});const{objectIdField:a,globalIdField:i}=t;if(!a||!i)throw new o("scenelayer:query-models-not-available","Missing required fields for model queries",{layer:e});const u=h(e,r,a,i),l=await t.queryFeatures(u,s);return await g(new S(e,t,w(l),n,s))}async function g(e){const{infoFor3D:t,associatedLayer:o,options:r}=e,s=o.globalIdField,n=o.parsedUrl;if(!s||!n)return new Map;const a=await I(e),f=new Map,c=await Promise.all(a.map(async({formatId:n,objectIds:a})=>{const f=i(n,t.supportedFormats),c=o.parsedUrl;if(null==f||!c||!a.length)return null;const m=u(n,t.supportedFormats),p=l(m),y=o.createQuery();y.objectIds=a,y.outFields=[s],y.formatOf3DObjects=n,y.returnGeometry=!0;return{modelFormat:f,modelFileExtensions:p,featureSetJSON:await d(c.path,y,{query:e.requestQuery,signal:r?.signal},{uniqueIdFields:o.uniqueIdFields})}}));for(const i of c)i&&j(e,i.modelFormat,i.modelFileExtensions,i.featureSetJSON,f);return f}async function F(e,t,o,r){const s=r?.format;return((await y(e,t,{objectIds:[o]},{...r,requestedFormat:s,sourceOnly:null==s})).get(o)??[]).find(e=>s&&e.format===s||!s&&e.isSource)}function w(e){const t=new Map;for(const o of e.features){const e=o.getObjectId(),r=o.getGlobalId();null!=e&&null!=r&&t.set(e,{globalId:r})}return t}async function I(e){const{options:o,infoFor3D:r,featureInfos:s}=e,n=[...s.keys()];if(o?.requestedFormat){const e=f(o.requestedFormat,r.supportedFormats);return e?[{formatId:e,objectIds:n}]:[]}const a=t([...r.queryFormats,...r.editFormats]);return await b(e,a)}async function b({options:e,infoFor3D:o,featureInfos:n,requestQuery:a,associatedLayer:i},u){const l=o.assetMapFieldRoles.parentGlobalId,f=o.assetMapFieldRoles.assetType,d=o.assetMapFieldRoles.flags,y=new Map;for(const[t,{globalId:r}]of n)r&&y.set(t,r);const g=t(y.values()),F=c(o);if(!F||!g.length)return[];const w=s(i.parsedUrl?.path??"",`../${F.id}`),I=!!e?.sourceOnly,b=new p({where:`${l} IN (${g.map(U).join(",")})`,outFields:I?[l,f,d]:[l,f],returnDistinctValues:!0,returnGeometry:!1}),{features:h}=await m(w,b,{query:a,signal:e?.signal}),q=new Set(u),j=new Map;for(const t of h){const e=t.getAttribute(l),o=t.getAttribute(f),s=t.getAttribute(d)??0;o&&q.has(o)&&e&&!(1&s)&&r(j,e,()=>new Set).add(o)}const D=new Map;for(const[t,s]of y)for(const e of j.get(s)??[])r(D,e,()=>[]).push(t);return u.map(e=>({formatId:e,objectIds:D.get(e)??[]})).filter(({objectIds:e})=>e.length>0)}function h(e,t,o,r){const s=q(e,t);return s.outFields=[o,r],s.returnGeometry=!1,s}function q(e,t){const o=p.from(t)?.clone()??e.createQuery();return o.outFields=null,o.formatOf3DObjects=null,o.returnGeometry=!1,o}function j({featureInfos:e,requestQuery:t,infoFor3D:o},s,n,i,u){const l=new Map;for(const a of i.assetMaps??[])r(l,a.parentGlobalId,()=>[]).push(a);for(const[f,c]of e){const e=l.get(c.globalId);if(!e?.length)continue;const i=D(e,t,o);if(!i.length)continue;const d=i.reduce((e,t)=>e+t.size,0),m=O(i,n),p=!m.flags.includes("DERIVED");r(u,f,()=>[]).push(new a({name:m.name,size:d,format:s,isSource:p,files:i}))}}function D(e,t,o){const s=new Map,a=({assetType:e})=>null!=i(e,o.supportedFormats),u=e.some(e=>a(e)&&!e.flags.includes("DERIVED"));for(const n of e)u&&a(n)&&n.flags.includes("DERIVED")||r(s,n.assetName,()=>[]).push(n);const l=[];for(const[r,i]of s){i.sort((e,t)=>e.seqNo-t.seqNo);const e=i.reduce((e,t)=>e+t.size,0),o=i.map(({assetURL:e})=>e).filter(e=>!!e);o.length&&l.push(new n({name:r,size:e,flags:i[0].flags,loadArrayBuffer:e=>M(o,t,e)}))}return l}async function M(t,o,r){const s=await Promise.all(t.map(t=>e(t,{responseType:"array-buffer",query:o,signal:r?.signal}).then(({data:e})=>e)));return 1===s.length?s[0]:E(s)}function O(e,t){return e.find(({name:e})=>t.some(t=>e.toLowerCase().endsWith(`.${t}`)))??e[0]}function U(e){return`'${e.replaceAll("'","''")}'`}function E(e){const t=e.reduce((e,t)=>e+t.byteLength,0),o=new Uint8Array(t);let r=0;for(const s of e)o.set(new Uint8Array(s),r),r+=s.byteLength;return o.buffer}class S{constructor(e,t,o,r,s){this.layer=e,this.associatedLayer=t,this.featureInfos=o,this.infoFor3D=r,this.options=s,this.requestQuery={...t.parsedUrl?.query,...e.customParameters,...e.apiKey?{token:e.apiKey}:{}}}}export{F as queryModel,y as queryModels};
