import{SCORE_FIELD as e,SCORE_FIELD_ORIGINAL as t}from"../../data/Feature.js";import{isSubtypeSublayer as r}from"../../utilities/_layers.js";import{AsyncQueue as s}from"../../utilities/asyncIterable.js";import{isSubtypeSublayerExtension as o}from"../../utilities/extensions.js";import{QueryError as i}from"../query/QueryError.js";import{SearchError as n}from"./SearchError.js";import{SearchOptions as u}from"./SearchOptions.js";import{SearchProviderBase as a}from"./SearchProviderBase.js";import{getSearchableValue as c}from"./_utilities.js";import{expandSearchArea as l,getSearchableFields as f,getWhereClause as d,initializeElasticlunrIndex as p,normalizeScores as y,separatorRegex as m}from"./support/_querySearchProviderUtils.js";export class SubtypeSublayerQuerySearchProvider extends a{_queryProvider;constructor(e){super(),this._queryProvider=e}isSupported(e){return o(e)&&r(e.sublayer)&&e.sublayer.layer&&e.layerExtension?.capabilities.supportsQuery}_search(r,a,h){const x=new s,g=new Map,w="__id",S=[],q=new Map,R=new Set,_=async()=>{let e=[a];if(h?.tokenizeSearchString??1){const{index:t,tokenizer:r}=await p(m);t.setRef(w),e=t.pipeline.run(this._queryProvider.getSearchTerms(a,r))}if(e.length)for(const t of r){const r={...u.DEFAULTS,...u.fromFeatureSource(t.layerExtension),spatialFilter:h?.initialSearchArea,tokenizeSearchString:!0,...h},s=f(t),o=d(t,e,s,r);if(!s.length||!o)continue;if(q.has(t.layerExtension)){q.get(t.layerExtension).sources.set(t,{fields:s,where:o});continue}const{index:i}=await p(m);i.setRef(w);for(const e of s)i.addField(e.name.toLowerCase());let{maxResults:n}=r;null!=r.maxQueryResults&&null!=r.maxResults&&(n=Math.max(r.maxQueryResults,r.maxResults));const a={...r,maxResults:n};R.add(t.layerExtension),q.set(t.layerExtension,{searchOptions:r,queryOptions:a,index:i,results:{count:0,lookup:new Map},sources:new Map([[t,{fields:s,where:o}]])})}},b=async e=>{const t=q.get(e),r=[];for(const[e,s]of t.sources)r.push({source:e,where:s.where,options:t.queryOptions});try{const e=this._queryProvider.queryService.query(r);for await(const t of e){if(x.isDone)return;const{source:e}=t;if(!o(e))continue;const{index:r,sources:s,results:{lookup:i}}=q.get(e.layerExtension),{fields:n}=s.get(e),u={};for(const e of n)u[e.name.toLowerCase()]=c(t,e);const a=`${e.id}-${t.primaryKey}`;!0!==g.get(a)?.queued&&(u[w]=a,r.addDoc(u),i.set(a,t),g.set(a,{feature:t,queued:!1}))}}catch(e){e instanceof i?S.push(e):S.push(new n([[[...t.sources.keys()],e]]))}},v=r=>{const{index:s,searchOptions:o,results:i}=q.get(r),n=s.search(a,{expand:!0});y(n);for(const s of n){const{feature:n,queued:u}=g.get(s.ref);if(n&&!u&&i.lookup.has(s.ref)&&(n.attributes.set(e,s.score),n.attributes.set(t,s.score),g.get(s.ref).queued=!0,x.add(n),i.lookup.delete(s.ref),i.count++),null!=o.maxResults&&i.count>=o.maxResults){R.delete(r);break}}for(const[s,n]of i.lookup){if(null!=o.maxResults&&i.count>=o.maxResults){R.delete(r);break}n.attributes.set(e,50),n.attributes.set(t,50),g.get(s).queued||(g.get(s).queued=!0,x.add(n),i.count++)}},j=async e=>{const{queryOptions:t,searchOptions:r,results:{count:s}}=q.get(e);if(null!=r.maxResults&&s>=r.maxResults)return void R.delete(e);const{scale:o,geometry:i}=await l(t.spatialFilter?.extent??void 0,e.getFullExtent(),r.currentScale,0===s?3:1);i?(t.spatialFilter=i,r.currentScale=o):R.delete(e)},k=async e=>{for(;R.size>0;){if(x.isDone)return;if(await b(e),x.isDone)return;v(e),await j(e)}};return(async()=>{await _();const e=[];for(const[t]of q)e.push(k(t));await Promise.all(e),S.length>0?x.reject(new n(S)):x.done()})(),x}async _count(e,t,r){return this._queryProvider.count(e,t,r)}_suggest(e,t,r){return this._queryProvider.suggest(e,t,r)}}