/* COPYRIGHT Esri - https://js.arcgis.com/5.1.2/LICENSE.txt */
import e from"../../request.js";import{isSome as t}from"../../core/arrayUtils.js";import{isDateString as i}from"../../core/date.js";import r from"../../core/Error.js";import{cacheAsync as n,getYieldedValue as o}from"../../core/iteratorUtils.js";import{_parseInfo as l}from"../../core/number.js";import{urlToObject as s}from"../../core/urlUtils.js";import a from"./Field.js";import{normalizeFieldName as c,getFieldDefaultLength as f}from"./fieldUtils.js";import{inferLocationInfo as u}from"./locationUtils.js";async function d(t,i={}){const{customParameters:n,signal:o}=i,l=s(t),a=await e(l.path,{query:{...l.query,...n},responseType:"native",signal:o});if(!a.data.body)throw new r("csv-utils:empty-csv","CSV is empty");const[c]=await Promise.allSettled([m(a.data.body)]);if(await a.data.body.cancel(),"rejected"===c.status)throw c.reason;return{url:t,customParameters:n,...c.value}}async function m(e){const t=e.getReader(),i=n(w(t)),l=i(),s=o(await l.next())?.trim(),c=o(await l.next())?.trim();if(!s)throw new r("csv-utils:empty-csv","CSV is empty");const{delimiter:f,locationInfo:u}=N(s,c);if(!f)throw new r("csv-utils:invalid-delimiter","Unable to detect the delimiter from CSV",{firstLine:s,secondLine:c});const{names:d,aliases:m}=S(s,f),p=i();await p.next();const y=await j(p,f,d,m,u);return t.releaseLock(),e.cancel().catch(()=>{}),{delimiter:f,fields:y.map(e=>a.fromJSON(e)),latitudeField:u?.latitudeFieldName,longitudeField:u?.longitudeFieldName}}const p=/^\s*"([\S\s]*)"\s*$/,y=/""/g,g="\n",h=[",",";","|","\t"];async function*w(e){const t=/\r?\n/gm,i=new TextDecoder;let r="";for await(const n of F(e)){const e=`${r}${i.decode(n)}`.split(t).filter(Boolean);r=e.pop()||"",yield*e}}async function*F(e){let t=await e.read();for(;!t.done;)yield t.value,t=await e.read();e.releaseLock()}function N(e,t,i){e=e.trim(),t=t?.trim();const r=[],n=Array.from(new Set([i?.delimiter,...h])).filter(e=>null!=e);for(const l of n){const i=v(e,l).length,n=v(t,l).length??i;i>1&&r.push({weight:Math.min(i,n),delimiter:l})}const o=r.sort(({weight:e},{weight:t})=>t-e).map(({delimiter:e})=>e);for(const l of o){const t=S(e,l).names,r=u(t,i?.longitudeField,i?.latitudeField);if(r.longitudeFieldName&&r.latitudeFieldName)return{delimiter:l,locationInfo:r}}return{delimiter:o[0],locationInfo:null}}async function*b(e,t,i,r=()=>Object.create(null)){let n="",o="",l=0,s=r(),a=0;for await(const c of e){const e=T(c,i);for(const c of e)if(n+=o+c,o="",l+=I(c),l%2==0){if(l>0){const e=p.exec(n);if(!e)return s=r(),a=0,n="",void(l=0);s[t[a]]=U(e[1]).replaceAll(y,'"'),a++}else s[t[a]]=U(n),a++;n="",l=0}else o=i;0===l?(yield s,s=r(),a=0):o=g}}function T(e,t){return x(e,t)}function*x(e,t){let i=0;for(;i<=e.length;){const r=e.indexOf(t,i),n=e.slice(i,r>-1?r:void 0);i+=n.length+t.length,yield n}}function S(e,i){const r=v(e,i).filter(t),n=r.map(e=>c(e));for(let t=n.length-1;t>=0;t--)n[t]||(n.splice(t,1),r.splice(t,1));return{names:n,aliases:r}}function v(e,t){if(!e?.length)return[];const i=[];let r="",n="",o=0;const l=T(e,t);for(const s of l)if(r+=n+s,n="",o+=I(s),o%2==0){if(o>0){const e=p.exec(r);e&&i.push(e[1].replaceAll(y,'"'))}else i.push(r);r="",o=0}else n=t;return i}async function j(e,t,i,r,n){const o=[],l=[];for await(const s of b(e,i,t)){if(10===l.length)break;l.push(s)}for(let s=0;s<i.length;s++){const e=i[s],t=r[s];if(e===n?.longitudeFieldName||e===n?.latitudeFieldName)o.push({name:e,type:"esriFieldTypeDouble",alias:t});else{const i=D(l.map(t=>t[e]))??"esriFieldTypeString";o.push({name:e,type:i,alias:t,length:f(i)})}}return o}function D(e){if(!e.length)return"esriFieldTypeString";const t=/[^+\-.,0-9]/;return e.map(e=>{if(""!==e){if(!t.test(e)){let t=O(e);if(!isNaN(t))return/[.,]/.test(e)||!Number.isInteger(t)||t>214783647||t<-214783648?"esriFieldTypeDouble":"esriFieldTypeInteger";if(e.includes("E")){if(t=Number(e),!Number.isNaN(t))return"esriFieldTypeDouble";if(e.includes(",")&&(e=e.replace(",","."),t=Number(e),!Number.isNaN(t)))return"esriFieldTypeDouble"}}return i(e)?"esriFieldTypeDate":"esriFieldTypeString"}}).reduce((e,t)=>void 0===e?t:void 0===t?e:e===t?t:"esriFieldTypeString"===e||"esriFieldTypeString"===t?"esriFieldTypeString":"esriFieldTypeDouble"===e||"esriFieldTypeDouble"===t?"esriFieldTypeDouble":void 0)}const O=function(){const e=l(),t=new RegExp("^"+e.regexp+"$"),i=new RegExp("["+e.group+"\\s\\xa0]","g"),r=e.factor;return n=>{const o=t.exec(n);if(e.factor=r,!o)return NaN;let l=o[1];if(!o[1]){if(!o[2])return NaN;l=o[2],e.factor*=-1}return l=l.replace(i,"").replace(e.decimal,"."),+l*e.factor}}();function U(e){return JSON.parse(JSON.stringify(e))}function I(e){let t=0,i=0;for(i=e.indexOf('"',i);i>=0;)t++,i=e.indexOf('"',i+1);return t}export{d as getCSVLayerInfo};
