const e=require("b4a"),i=require("hypercore-crypto"),{KeetContractError:r}=require("./errors"),{fileStats:n}=require("./stats"),t=524288;async function a(n,a,l){if(!a&&!l)return;if(!b(l))return;if(l.preview&&(l.preview=null),!l.pointer.inlined&&l.pointer.blob&&(l.pointer.blob=null),!l||!l.pointer.inlined)return a||l;if(a&&a.hash&&l.hash&&e.equals(a.hash,l.hash))return{...l,pointer:a.pointer};if(l.pointer.inlined.byteLength>t)throw r.INLINED_FILESIZE_TOO_LARGE("Cannot inline a blob that is larger than 512 KB");const s=i.hash(l.pointer.inlined);return await n.insert("@keet/blobs",{hash:s,data:l.pointer.inlined}),{...l,pointer:{bee:{hash:s}}}}async function l(e,i,r){return{small:await a(e,i?.small,r?.small),medium:await a(e,i?.medium,r?.medium),large:await a(e,i?.large,r?.large)}}async function s(e,i,r){r&&await Promise.all([o(e,i,r.small),o(e,i,r.medium),o(e,i,r.large)])}async function o(e,i,r){if(r)if(r.pointer.bee){const i=await e.get("@keet/blobs",r.pointer.bee);r.pointer={inlined:i.data}}else if(r.pointer.blob&&i){const e=await i.get(r.pointer.blob);r.pointer={inlined:e}}}async function p({primaryThread:e,id:i,db:r,oplog:t,file:a}){a.preview&&(a.preview=await l(r,null,a.preview)),a.pointer.inlined&&(a.pointer.inlined=null),a.pointer.blob&&(a.pointer.blob=null);const s={id:i,oplog:t,status:{isDeleted:!1},file:a};return await r.insert("@keet/files",s),await n(r,e,s),i}async function u({primaryThread:e,files:i,id:n,blobs:t,db:a,oplog:l}){if(!i||i.length<1)return[];if(!function(e){const i=Array.isArray(e)?e:[e];for(const e of i)if(!b(e))return!1;return!0}(i))throw r.FILE_RECORD_INVALID();const s=[];for(const r of i)s.push(await p({primaryThread:e,id:n++,blobs:t,db:a,oplog:l,file:r}));return s}async function f({primaryThread:e,clock:i,links:r,blobs:n,db:t,oplog:a}){let l=0;for(const s of r)s.preview?.files&&(s.preview.files=[]),s.preview?.file&&(s.preview.files=await u({primaryThread:e,id:i+l,files:[s.preview.file],blobs:n,db:t,oplog:a}),l+=s.preview.files.length)}async function d({primaryThread:e,files:i,db:r,blobs:t}){if(!i||!i.length)return;const a=await Promise.all(i.map(e=>r.get("@keet/files",{id:e}))),l=[];for(const i of a)i.status.isDeleted=!0,l.push(r.insert("@keet/files",i)),l.push(n(r,e,i,i));await Promise.all(l)}function c(i,r){return!i&&!r||!(!i&&r)&&!(i&&!r)&&(i.hash&&r.hash?e.equals(i.hash,r.hash):e.equals(i.pointer.inlined,r.pointer.inlined))}function b(e){return e.preview&&(e.preview?.small?.preview&&(e.preview.small.preview=null),e.preview?.medium?.preview&&(e.preview.medium.preview=null),e.preview?.large?.preview&&(e.preview.large.preview=null)),!(e.pointer.externalDrive&&!e.pointer.externalDrive.path||e.pointer.externalDrive&&e.pointer.externalBlob)}module.exports={isSameAvatar:function(e,i){const r=c(e?.small,i?.small),n=c(e?.medium,i?.medium),t=c(e?.large,i?.large);return r&&n&&t},updateAvatar:async function(e,i,r){return await l(e,i,r)},updateImageFile:l,restoreAvatar:async function(e,i,r){return s(e,i,r)},restoreFile:s,insertMessageFiles:async function({primaryThread:e,clock:i,message:r,blobs:n,db:t,oplog:a}){const l=r.files||[],s=await u({primaryThread:e,files:l,id:i,blobs:n,db:t,oplog:a});return await async function({primaryThread:e,clock:i,message:r,blobs:n,db:t,oplog:a}){const l=r?.display?.httpLink||[],s=r?.display?.pearLink||[];await f({primaryThread:e,clock:i,links:[...l,...s],blobs:n,db:t,oplog:a})}({primaryThread:e,clock:i+l.length,message:r,blobs:n,db:t,oplog:a}),s},insertLinkPreviewFiles:f,deleteMessageFiles:async function({primaryThread:e,message:i,db:r,blobs:n}){const t=i.message?.files||[],a=i.message?.display?.httpLink||[];for(const{preview:e}of a)e&&e.files&&e.files.length&&t.push(...e.files);const l=i.message?.display?.pearLink||[];for(const{preview:e}of l)e&&e.files&&e.files.length&&t.push(...e.files);await d({primaryThread:e,files:t,db:r,blobs:n})},deleteFileRecord:d,MAX_INLINED_FILE_SIZE:t};