/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import{splitIntoChunks as e}from"../../../core/arrayUtils.js";import{lerp as t}from"../../../core/mathUtils.js";import{throwIfAborted as r,after as o,isAbortError as n,throwIfNotAbortError as s}from"../../../core/promiseUtils.js";import i from"../../../geometry/Multipoint.js";import{unnormalizedCoordinate as l}from"../../../geometry/support/coordsUtils.js";import{getInfo as a}from"../../../geometry/support/spatialReferenceUtils.js";import{ScheduledQueueProcessor as c}from"../../../views/support/ScheduledQueueProcessor.js";import{TaskPriority as u}from"../../../views/support/Scheduler.js";import{getConfig as p,errorResult as f}from"./constants.js";import{isValidInputPath as m,countPoints as d,densifyPath as h}from"./geometryUtils.js";import{ProfileGenerationError as y}from"./ProfileGenerationError.js";import{getStatistics as w}from"./statisticsUtils.js";import{breadthFirstBinaryPartitioning as g}from"../../support/traversalUtils.js";async function*v(e,t){const{view:n,geometry:s,elevationInfo:i,providers:l,options:a}=e,c=n.spatialReference;if(!c||null==s||!m(s))throw new y("invalid-geometry");const u=l.length;if(0===u)return null;const f=Math.round(a.maxTotalSamples/u);if(d(s)>f)throw new y("too-complex");const w=await h(s,i,n,c,a,f,t);let g=0;const v=new Array(u),j=new Array(u);for(let r=0;r<u;r++){const o=S(w);v[r]=o,g+=o.samples.length;const n={...e,provider:l[r],result:o,densificationResult:w};j[r]=P(n,t)[Symbol.iterator]()}if(g>a.maxTotalSamples)throw new y("too-complex");const R=await Promise.all(j.map(e=>{const t=e.next();return!0===t.done?Promise.resolve(null):t.value}));r(t);for(let r=0;r<u;r++)v[r]=R[r];yield v,await o(e.delayAfterPreview??p().delayAfterPreviewMillis,null,t.signal);const Z=[];try{let e;do{e=!1;for(let t=0;t<u;t++){const r=j[t].next();!1===r.done&&(Z.push({resultPromise:r.value,index:t}),e=!0)}}while(e)}finally{j.forEach(e=>e.return?.())}for(const{resultPromise:o,index:p}of Z)v[p]=await o,r(t),yield v;for(const r of v)null!=r&&(r.progress=1);yield v}function*P(t,r){const{densificationResult:o}=t,n={...t,abortOptions:r,densificationResult:o},s=g(0,n.result.samples.length),i=s.slice(0,n.provider.numSamplesForPreview);yield j(n,i,!0);const l=e(s,n.provider.numSamplesPerChunk);for(const e of l)yield j(n,e,!1)}async function j({densificationResult:e,result:t,provider:r,queue:o,abortOptions:s,cache:l},a,c){const{densifiedPath:u,pathLength:m}=e,d=t.spatialReference,{samples:h}=t,y=[];for(let n=0;n<a.length;n++){const e=h[a[n]];y[n]=[...e.coordinate]}try{return await o.push({geometry:new i({spatialReference:d,points:y,hasZ:u.hasZ}),provider:r,indices:a,preview:c,result:t,queryOptions:{...p().defaultQueryOptions(),minDemResolution:c?Math.round(m/r.numSamplesForPreview):Math.round(m/h.length),cache:l}},s),{...t}}catch(w){return n(w)?null:f}}function R(e){return new c({priority:u.ELEVATION_PROFILE,concurrency:1,scheduler:e,process:async e=>{r(e.queryOptions);try{await Z(e)}catch(t){s(t)}}})}async function Z({geometry:e,provider:t,indices:r,preview:o,result:n,queryOptions:s}){if(0===r.length)return;const i=(await M(t,e,s)).geometry,{hasZ:l,points:a}=i,c=s.noDataValue,{samples:u}=n;for(let p=0;p<r.length;p++){const e=u[r[p]];if(e.isHole)continue;const t=l?a[p][2]:null;null===t||t===c?e.sampledZ=null:(n.hasZ=!0,e.sampledZ=t),e.sampled=!0}x(u),n.progress=o?0:n.progress+r.length/u.length,n.statistics=w(n.samples,n.spatialReference)}function x(e){const t=e.length-1;let r=0;for(let o=1;o<=t;o++){(e[o].sampled||o===t)&&(O(e,r,o),r=o)}}function O(e,r,o){if(o-r===1)return;const n=e[r],s=n.sampledZ,i=e[o],l=i.sampledZ;if(null==s||null==l){for(let t=r+1;t<o;t++)e[t].sampledZ=null;return}const a=n.distance,c=i.distance-a;for(let u=r+1;u<o;u++){const r=e[u],o=(r.distance-a)/c;r.sampledZ=t(s,l,o)}}function S({densifiedPath:e,distances:t}){const r=e.spatialReference,o=a(r),n=e.paths,s=n.length,i=[];let c=null,u=0;for(let a=0;a<s;a++){const e=n[a],r=e.length,s=t[a];for(let t=0;t<r;t++){const r=e[t],n=s[t];o&&(r[0]=l(r[0],o.valid[0],o.valid[1])),c&&0===t&&U(i,c,r,u,n),i.push(q(r,n)),c=r,u=n}}return{progress:0,samples:i,hasZ:!1,statistics:null,spatialReference:r}}function U(e,t,r,o,n){e.push(E(t,o)),e.push(E(r,n))}function q(e,t){return{coordinate:e,distance:t,sampledZ:null,sampled:!1,isHole:!1}}function E(e,t){return{coordinate:e,distance:t,sampledZ:null,sampled:!0,isHole:!0}}async function M(e,t,r){try{return await e.queryElevation(t,r)}catch(o){throw new y("elevation-query-error")}}function A(e,t,r){if(!e||0===e.length)return;const o=e.length-1,n=e[0];if(t<=r(n))return n;const s=e[o];if(t>=r(s))return s;let i=0,l=0,a=o;for(;i<a;){l=i+Math.floor((a-i)/2);const n=e[l],s=r(n);if(s===t)return n;if(t<s){if(l>0){const o=e[l-1],i=r(o);if(t>i)return t-i>=s-t?n:o}a=l}else{if(l<o){const o=e[l+1],i=r(o);if(t<i)return t-s>=i-t?o:n}i=l+1}}return e[l]}export{A as binaryFindClosest,R as createProfileQueue,P as generateProfile,v as generateProfiles,x as interpolateElevations};
