import path from 'path'
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
import downloadFiles from './downloadFiles.mjs'
//fnExe, processStatus執行檔名稱
let fnExe = 'processStatus.exe'
//pmDownload, 下載中之Promise, 供併發呼叫共用同一次下載, 避免同時多次下載寫入同一批檔案
let pmDownload = null
/**
* 自動定位processStatus.exe,若無檔案則自動下載,回傳processStatus.exe的絕對路徑
*
* 依序偵測當前工作路徑的src/與node_modules/w-process-status/src/,皆無processStatus.exe時,
* 代表安裝時npm封鎖scripts致postinstall未執行,故自動調用downloadFiles重新下載
*
* 供w-process-status自身與其他依賴w-process-status的套件調用,無須各自實作偵測與下載邏輯
*
* 因processStatus.exe只能用於Windows作業系統,故調用前須自行檢核作業系統
*
* @returns {Promise} 回傳Promise,resolve回傳執行檔路徑物件,內含fpExe為processStatus.exe的絕對路徑字串,reject回傳錯誤訊息
* @example
* import autoDownloadFiles from 'w-process-status/src/autoDownloadFiles.mjs'
*
* async function test() {
*
* //autoDownloadFiles, 無processStatus.exe時自動下載, 下載失敗則reject
* let { fpExe } = await autoDownloadFiles()
*
* console.log('fpExe', fpExe)
* // fpExe D:\xxx\node_modules\w-process-status\src\processStatus.exe
* }
* test()
* .catch((err) => {
* console.log('catch', err)
* })
*
*/
async function autoDownloadFiles() {
//fdSrv, 於調用時取當前工作路徑
let fdSrv = path.resolve()
//fdBaseSelf, fdBaseNM, processStatus.exe可能所在資料夾(開發套件本身時於cwd的src/, 被安裝為相依套件時於node_modules/w-process-status/src/)
let fdBaseSelf = `${fdSrv}/src/`
let fdBaseNM = `${fdSrv}/node_modules/w-process-status/src/`
//fdBase
let fdBase = ''
if (fsIsFile(`${fdBaseSelf}${fnExe}`)) {
fdBase = fdBaseSelf
}
else if (fsIsFile(`${fdBaseNM}${fnExe}`)) {
fdBase = fdBaseNM
}
else {
//fdBaseDL, 下載落點, 有node_modules/w-process-status/代表為被安裝之相依套件, 否則為套件自身
let fdBaseDL = fsIsFolder(`${fdSrv}/node_modules/w-process-status/`) ? fdBaseNM : fdBaseSelf
//downloadFiles, 無processStatus.exe代表安裝時npm封鎖scripts致postinstall未執行, 故於此重新執行下載,
//併發呼叫共用同一個下載Promise, 避免重複下載
if (pmDownload === null) {
pmDownload = downloadFiles(fdBaseDL)
.catch((err) => {
//下載失敗歸零, 使下次呼叫可重試下載
pmDownload = null
return Promise.reject(err)
})
}
await pmDownload
//check
if (fsIsFile(`${fdBaseDL}${fnExe}`)) {
fdBase = fdBaseDL
}
}
//check
if (fdBase === '') {
return Promise.reject('can not find processStatus.exe')
}
//fpExe
let fpExe = path.resolve(fdBase, fnExe)
return {
fpExe,
}
}
export default autoDownloadFiles