/*
All material copyright Esri, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/5.0/esri/copyright.txt for details.
*/
import{neverReached as e}from"../../../core/compilerUtils.js";import t from"../../../core/Error.js";import{whenOrAbort as s,throwIfAborted as r,allSettledValues as o,isAborted as n,createAbortError as i}from"../../../core/promiseUtils.js";import{removeFile as a,makeRelative as l}from"../../../core/urlUtils.js";import c from"../../Point.js";async function u(t,s,r){switch(s.source.type){case"client":case"service":return m(t,s,r);case"loadable":return s.source.load(t,r);default:e(s.source)}}async function m(e,o,n){const{source:i}=o,{loadGLTFMesh:a}=await s(import("./loadGLTFMesh.js"),n),l=await p(i,n);r(n);const u=a(new c({x:0,y:0,z:0,spatialReference:e.spatialReference}),l.url,{resolveFile:f(l),signal:n?.signal,expectedType:l.type,unitConversionDisabled:o.unitConversionDisabled});u.then(()=>l.dispose(),()=>l.dispose());const{mesh:{vertexAttributes:m,components:d},meta:{isDracoDecompressed:h}}=await u;if(h)throw new t("mesh-load-external:draco-not-supported","The provided mesh uses Draco compression which is not supported.");e.vertexAttributes=m,e.components=d}function f(e){const t=a(e.url);return s=>{const r=l(s,t,t),o=r?r.replace(/^ *\.\//,""):null;return(o?e.files.get(o):null)??s}}async function p(e,s){switch(e.type){case"client":return Array.isArray(e.files)?w(e.files):h(e.files);case"service":return y(e.assets,s);default:throw new t("mesh-load-external:invalid-source","Invalid source type")}}async function d(e,t){const{parts:s,assetMimeType:o,assetName:n}=e;if(1===s.length)return new M(s[0].partUrl);const i=await e.toBlob(t);return r(t),M.fromBlob(i,R(n,o))}function h(e){return M.fromBlob(e,R(e.name,e.type))}function w(e){if(!e.length)throw new t("mesh-load-external:missing-assets","There must be at least one file to load");return j(e.map(e=>({name:e.name,mimeType:e.type,source:h(e)})))}async function y(e,s){if(!e.length)throw new t("mesh-load-external:missing-assets","There must be at least one file to load");const a=await o(e.map(async e=>{const t=await d(e);return r(s),{name:e.assetName,mimeType:e.assetMimeType,source:t}}));if(n(s))throw a.forEach(e=>e.source.dispose()),i();return j(a)}const g=/^model\/gltf\+json$/,b=/^model\/gltf-binary$/,v=/\.gltf$/i,x=/\.glb$/i;function T({mimeType:e,source:t,name:s}){return g.test(e)||v.test(s)?{url:t.url,type:"gltf"}:b.test(e)||x.test(s)?{url:t.url,type:"glb"}:null}function j(e){const s=new Map;let r=null,o=null;for(const t of e){const{source:e,name:n}=t;r??=T(t),"ESRI3DO_NORM.glb"===n&&(o=T(t)),s.set(n,e.url),e.files.forEach((e,t)=>s.set(t,e))}const n=o??r;if(null==n)throw new t("mesh-load-external:missing-files","Missing files to load external mesh source");return new M(n.url,()=>e.forEach(({source:e})=>e.dispose()),s,n.type)}class M{constructor(e,t=()=>{},s=new Map,r){this.url=e,this.dispose=t,this.files=s,this.type=r}static fromBlob(e,t){const s=URL.createObjectURL(e);return new M(s,()=>URL.revokeObjectURL(s),void 0,t)}}function R(e,t){return g.test(t)||v.test(e)?"gltf":b.test(t)||v.test(e)?"glb":void 0}export{u as loadExternal};
