import{isNode}from"../environment.js";import{assert}from"./assert.js";import{debug}from"./Debug.js";import{TimeoutError}from"./Errors.js";export const debugError=debug("puppeteer:error");function getExceptionMessage(e){if(e.exception)return e.exception.description||e.exception.value;let t=e.text;if(e.stackTrace)for(const n of e.stackTrace.callFrames){const e=n.url+":"+n.lineNumber+":"+n.columnNumber;t+=`\n    at ${n.functionName||"<anonymous>"} (${e})`}return t}function valueFromRemoteObject(e){if(assert(!e.objectId,"Cannot extract value when objectId is given"),e.unserializableValue){if("bigint"===e.type&&"undefined"!==typeof BigInt)return BigInt(e.unserializableValue.replace("n",""));switch(e.unserializableValue){case"-0":return-0;case"NaN":return NaN;case"Infinity":return 1/0;case"-Infinity":return-1/0;default:throw new Error("Unsupported unserializable value: "+e.unserializableValue)}}return e.value}async function releaseObject(e,t){t.objectId&&await e.send("Runtime.releaseObject",{objectId:t.objectId}).catch((e=>{debugError(e)}))}function addEventListener(e,t,n){return e.on(t,n),{emitter:e,eventName:t,handler:n}}function removeEventListeners(e){for(const t of e)t.emitter.removeListener(t.eventName,t.handler);e.length=0}function isString(e){return"string"===typeof e||e instanceof String}function isNumber(e){return"number"===typeof e||e instanceof Number}async function waitForEvent(e,t,n,r,i){let o,a,s;const u=new Promise(((e,t)=>{a=e,s=t})),c=addEventListener(e,t,(async e=>{await n(e)&&a(e)}));function l(){removeEventListeners([c]),clearTimeout(o)}r&&(o=setTimeout((()=>{s(new TimeoutError("Timeout exceeded while waiting for event"))}),r));const d=await Promise.race([u,i]).then((e=>(l(),e)),(e=>{throw l(),e}));if(d instanceof Error)throw d;return d}function evaluationString(e,...t){if(isString(e))return assert(0===t.length,"Cannot evaluate a string with arguments"),e;return`(${e})(${t.map((function(e){return Object.is(e,void 0)?"undefined":JSON.stringify(e)})).join(",")})`}function pageBindingInitString(e,t){return evaluationString((function(e,t){const n=window,r=n[t];n[t]=(...n)=>{const i=window[t];let o=i.callbacks;o||(o=new Map,i.callbacks=o);const a=(i.lastSeq||0)+1;i.lastSeq=a;const s=new Promise(((e,t)=>o.set(a,{resolve:e,reject:t})));return r(JSON.stringify({type:e,name:t,seq:a,args:n})),s}}),e,t)}function pageBindingDeliverResultString(e,t,n){return evaluationString((function(e,t,n){window[e].callbacks.get(t).resolve(n),window[e].callbacks.delete(t)}),e,t,n)}function pageBindingDeliverErrorString(e,t,n,r){return evaluationString((function(e,t,n,r){const i=new Error(n);i.stack=r,window[e].callbacks.get(t).reject(i),window[e].callbacks.delete(t)}),e,t,n,r)}function pageBindingDeliverErrorValueString(e,t,n){return evaluationString((function(e,t,n){window[e].callbacks.get(t).reject(n),window[e].callbacks.delete(t)}),e,t,n)}function makePredicateString(e,t){return`\n    (() => {\n      ${t?`const predicateQueryHandler = ${t};`:""}\n      const checkWaitForOptions = ${function(e,t,n){if(!e)return n;if(!t&&!n)return e;const r=e.nodeType===Node.TEXT_NODE?e.parentElement:e,i=window.getComputedStyle(r),o=i&&"hidden"!==i.visibility&&function(){const e=r.getBoundingClientRect();return!!(e.top||e.bottom||e.width||e.height)}();return t===o||n===!o?e:null}};\n      return (${e})(...args)\n    })() `}async function waitWithTimeout(e,t,n){let r;const i=new TimeoutError(`waiting for ${t} failed: timeout ${n}ms exceeded`),o=new Promise(((e,t)=>r=t));let a=null;n&&(a=setTimeout((()=>r(i)),n));try{return await Promise.race([e,o])}finally{a&&clearTimeout(a)}}async function readProtocolStream(e,t,n){if(!isNode&&n)throw new Error("Cannot write to a path outside of Node.js environment.");const r=isNode?await importFSModule():null;let i,o=!1;n&&r&&(i=await r.promises.open(n,"w"));const a=[];for(;!o;){const s=await e.send("IO.read",{handle:t});o=s.eof;const u=Buffer.from(s.data,s.base64Encoded?"base64":void 0);a.push(u),n&&r&&await r.promises.writeFile(i,u)}n&&await i.close(),await e.send("IO.close",{handle:t});let s=null;try{s=Buffer.concat(a)}finally{return s}}async function importFSModule(){if(!isNode)throw new Error("Cannot load the fs module API outside of Node.");const e=await import("fs");return e.promises?e:e.default}export const helper={evaluationString:evaluationString,pageBindingInitString:pageBindingInitString,pageBindingDeliverResultString:pageBindingDeliverResultString,pageBindingDeliverErrorString:pageBindingDeliverErrorString,pageBindingDeliverErrorValueString:pageBindingDeliverErrorValueString,makePredicateString:makePredicateString,readProtocolStream:readProtocolStream,waitWithTimeout:waitWithTimeout,waitForEvent:waitForEvent,isString:isString,isNumber:isNumber,importFSModule:importFSModule,addEventListener:addEventListener,removeEventListeners:removeEventListeners,valueFromRemoteObject:valueFromRemoteObject,getExceptionMessage:getExceptionMessage,releaseObject:releaseObject};