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