"use strict";const fs=require("fs"),path=require("path"),{promisify}=require("util"),{cppdb}=require("../util"),fsAccess=promisify(fs.access);module.exports=async function(e,t){if(null==t&&(t={}),"string"!=typeof e)throw new TypeError("Expected first argument to be a string");if("object"!=typeof t)throw new TypeError("Expected second argument to be an options object");e=e.trim();const r="attached"in t?t.attached:"main",n="progress"in t?t.progress:null;if(!e)throw new TypeError("Backup filename cannot be an empty string");if(":memory:"===e)throw new TypeError('Invalid backup filename ":memory:"');if("string"!=typeof r)throw new TypeError('Expected the "attached" option to be a string');if(!r)throw new TypeError('The "attached" option cannot be an empty string');if(null!=n&&"function"!=typeof n)throw new TypeError('Expected the "progress" option to be a function');await fsAccess(path.dirname(e)).catch(()=>{throw new TypeError("Cannot save backup because the directory does not exist")});const o=await fsAccess(e).then(()=>!1,()=>!0);return runBackup(this[cppdb].backup(this,r,e,o),n||null)};const runBackup=(e,t)=>{let r=0,n=!0;return new Promise((o,i)=>{setImmediate(function s(){try{const i=e.transfer(r);if(!i.remainingPages)return e.close(),void o(i);if(n&&(n=!1,r=100),t){const e=t(i);if(void 0!==e){if("number"!=typeof e||e!=e)throw new TypeError("Expected progress callback to return a number or undefined");r=Math.max(0,Math.min(2147483647,Math.round(e)))}}setImmediate(s)}catch(t){e.close(),i(t)}})})};