import fs from 'fs'
import get from 'lodash-es/get.js'
import isestr from 'wsemi/src/isestr.mjs'
import isbol from 'wsemi/src/isbol.mjs'
import isp0int from 'wsemi/src/isp0int.mjs'
import isfun from 'wsemi/src/isfun.mjs'
import cdbl from 'wsemi/src/cdbl.mjs'
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
import fsCleanFolder from 'wsemi/src/fsCleanFolder.mjs'
import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
import fsCopyFolder from 'wsemi/src/fsCopyFolder.mjs'
import fsDeleteFolder from 'wsemi/src/fsDeleteFolder.mjs'
import WDwdataFtp from 'w-dwdata-ftp/src/WDwdataFtp.mjs'
import parseData from './parseData.mjs'
/**
* 基於檔案之下載台灣氣象署FTP地震數據與任務建構器
*
* 執行階段最新hash數據放置於fdDwAttime,前次hash數據會於結束前自動備份至fdDwCurrent
*
* 執行階段最新數據放置於fdDwStorageTemp,前次數據放置於fdDwStorage,於結束前會將fdDwStorage清空,將fdDwStorageTemp複製至fdDwStorage
*
* @param {String} st 輸入設定FTP連線資訊物件
* @param {String} [st.transportation='FTP'] 輸入傳輸協定字串,可選'FTP'、'SFTP',預設'FTP'
* @param {String} [st.hostname=''] 輸入hostname字串,預設''
* @param {Integer} [st.port=21|22] 輸入port正整數,當transportation='FTP'預設21,當transportation='SFTP'預設22
* @param {String} [st.username=''] 輸入帳號字串,預設''
* @param {String} [st.password=''] 輸入密碼字串,預設''
* @param {String} [st.fdIni='./'] 輸入同步資料夾字串,預設'./'
* @param {Object} [opt={}] 輸入設定物件,預設{}
* @param {String} [opt.fdTagRemove='./_tagRemove'] 輸入暫存標記為刪除數據資料夾字串,預設'./_tagRemove'
* @param {String} [opt.fdDwStorageTemp='./_dwStorageTemp'] 輸入最新下載檔案存放資料夾字串,預設'./_dwStorageTemp'
* @param {String} [opt.fdDwStorage='./_dwStorage'] 輸入合併儲存檔案資料夾字串,預設'./_dwStorage'
* @param {String} [opt.fdDwAttime='./_dwAttime'] 輸入當前下載供比對hash用之數據資料夾字串,預設'./_dwAttime'
* @param {String} [opt.fdDwCurrent='./_dwCurrent'] 輸入已下載供比對hash用之數據資料夾字串,預設'./_dwCurrent'
* @param {String} [opt.fdResultTemp=`./_resultTemp`] 輸入若有變更數據時,儲存前次已下載數據所連動生成數據資料夾字串,預設`./_resultTemp`
* @param {String} [opt.fdResult='./_result'] 輸入已下載數據所連動生成數據資料夾字串,預設'./_result'
* @param {String} [opt.fdTaskCpActualSrc='./_taskCpActualSrc'] 輸入任務狀態之來源端完整資料夾字串,預設'./_taskCpActualSrc'
* @param {String} [opt.fdTaskCpSrc='./_taskCpSrc'] 輸入任務狀態之來源端資料夾字串,預設'./_taskCpSrc'
* @param {String} [opt.fdLog='./_logs'] 輸入儲存log資料夾字串,預設'./_logs'
* @param {Function} [opt.funDownload=null] 輸入當前下載數據hash之函數,回傳資料陣列,預設null
* @param {Function} [opt.funGetCurrent=null] 輸入已下載數據hash之函數,回傳資料陣列,預設null
* @param {Function} [opt.funAdd=null] 輸入當有新資料時,需要連動處理之函數,預設null
* @param {Function} [opt.funModify=null] 輸入當有資料需更新時,需要連動處理之函數,預設null
* @param {Function} [opt.funRemove=null] 輸入當有資料需刪除時,需要連動處理之函數,預設null
* @param {Number} [opt.timeToleranceRemove=0] 輸入刪除任務之防抖時長,單位ms,預設0,代表不使用
* @returns {Object} 回傳事件物件,可呼叫函數on監聽change事件
* @example
*
* import w from 'wsemi'
* import WDwdataTweqmp from './src/WDwdataTweqmp.mjs'
*
* let st = {
* 'hostname': '{hostname}',
* 'port': 21,
* 'username': '{username}',
* 'password': '{password}',
* 'fdIni': './'
* }
*
* //fdTagRemove
* let fdTagRemove = `./_tagRemove`
* w.fsCleanFolder(fdTagRemove)
*
* //fdDwStorageTemp
* let fdDwStorageTemp = `./_dwStorageTemp`
* w.fsCleanFolder(fdDwStorageTemp)
*
* //fdDwStorage
* let fdDwStorage = `./_dwStorage`
* w.fsCleanFolder(fdDwStorage)
*
* //fdDwAttime
* let fdDwAttime = `./_dwAttime`
* w.fsCleanFolder(fdDwAttime)
*
* //fdDwCurrent
* let fdDwCurrent = `./_dwCurrent`
* w.fsCleanFolder(fdDwCurrent)
*
* //fdResultTemp
* let fdResultTemp = './_resultTemp'
* w.fsCleanFolder(fdResultTemp)
*
* //fdResult
* let fdResult = './_result'
* w.fsCleanFolder(fdResult)
*
* //fdTaskCpActualSrc
* let fdTaskCpActualSrc = `./_taskCpActualSrc`
* w.fsCleanFolder(fdTaskCpActualSrc)
*
* //fdTaskCpSrc
* let fdTaskCpSrc = `./_taskCpSrc`
* w.fsCleanFolder(fdTaskCpSrc)
*
* let opt = {
* fdTagRemove,
* fdDwStorageTemp,
* fdDwStorage,
* fdDwAttime,
* fdDwCurrent,
* fdResultTemp,
* fdResult,
* fdTaskCpActualSrc,
* fdTaskCpSrc,
* // fdLog,
* // funDownload,
* // funGetCurrent,
* // funRemove,
* // funAdd,
* // funModify,
* }
* let ev = await WDwdataTweqmp(st, opt)
* .catch((err) => {
* console.log(err)
* })
* ev.on('change', (msg) => {
* delete msg.type
* console.log('change', msg)
* })
* // change { event: 'start', msg: 'running...' }
* // change { event: 'proc-callfun-download', msg: 'start...' }
* // change { event: 'proc-callfun-download', num: 2, msg: 'done' }
* // change { event: 'proc-callfun-getCurrent', msg: 'start...' }
* // change { event: 'proc-callfun-getCurrent', num: 0, msg: 'done' }
* // change { event: 'proc-compare', msg: 'start...' }
* // change { event: 'proc-compare', numRemove: 0, numAdd: 2, numModify: 0, numSame: 0, msg: 'done' }
* // change { event: 'proc-add-callfun-add', id: '100000-townshipInt-All.txt', msg: 'start...' }
* // change { event: 'proc-add-callfun-add', id: '100000-townshipInt-All.txt', msg: 'done' }
* // change { event: 'proc-add-callfun-add', id: '100001-townshipInt-All.txt', msg: 'start...' }
* // change { event: 'proc-add-callfun-add', id: '100001-townshipInt-All.txt', msg: 'done' }
* // ...
*
*/
let WDwdataTweqmp = async(st, opt = {}) => {
// //useExpandOnOldFiles
// let useExpandOnOldFiles = get(opt, 'useExpandOnOldFiles')
// if (!isbol(useExpandOnOldFiles)) {
// useExpandOnOldFiles = false
// }
//useSimulateFiles, 供測試用, 檔案得預先給予至fdDwStorageTemp
let useSimulateFiles = get(opt, 'useSimulateFiles')
if (!isbol(useSimulateFiles)) {
useSimulateFiles = false
}
//fdTagRemove, 暫存標記為刪除數據資料夾
let fdTagRemove = get(opt, 'fdTagRemove')
if (!isestr(fdTagRemove)) {
fdTagRemove = `./_tagRemove`
}
//fdDwStorageTemp, 最新下載檔案存放資料夾
let fdDwStorageTemp = get(opt, 'fdDwStorageTemp')
if (!isestr(fdDwStorageTemp)) {
fdDwStorageTemp = `./_dwStorageTemp`
}
if (!fsIsFolder(fdDwStorageTemp)) {
fsCreateFolder(fdDwStorageTemp)
}
//fdDwStorage, 合併儲存檔案資料夾
let fdDwStorage = get(opt, 'fdDwStorage')
if (!isestr(fdDwStorage)) {
fdDwStorage = `./_dwStorage`
}
if (!fsIsFolder(fdDwStorage)) {
fsCreateFolder(fdDwStorage)
}
//fdDwAttime
let fdDwAttime = get(opt, 'fdDwAttime')
if (!isestr(fdDwAttime)) {
fdDwAttime = `./_dwAttime`
}
if (!fsIsFolder(fdDwAttime)) {
fsCreateFolder(fdDwAttime)
}
//fdDwCurrent
let fdDwCurrent = get(opt, 'fdDwCurrent')
if (!isestr(fdDwCurrent)) {
fdDwCurrent = `./_dwCurrent`
}
if (!fsIsFolder(fdDwCurrent)) {
fsCreateFolder(fdDwCurrent)
}
//fdResultTemp
let fdResultTemp = get(opt, 'fdResultTemp')
if (!isestr(fdResultTemp)) {
fdResultTemp = `./_resultTemp`
}
if (!fsIsFolder(fdResultTemp)) {
fsCreateFolder(fdResultTemp)
}
//fdResult
let fdResult = get(opt, 'fdResult')
if (!isestr(fdResult)) {
fdResult = './_result'
}
if (!fsIsFolder(fdResult)) {
fsCreateFolder(fdResult)
}
//fdTaskCpActualSrc, 儲存完整任務狀態資料夾
let fdTaskCpActualSrc = get(opt, 'fdTaskCpActualSrc')
if (!isestr(fdTaskCpActualSrc)) {
fdTaskCpActualSrc = `./_taskCpActualSrc`
}
if (!fsIsFolder(fdTaskCpActualSrc)) {
fsCreateFolder(fdTaskCpActualSrc)
}
//fdTaskCpSrc
let fdTaskCpSrc = get(opt, 'fdTaskCpSrc')
if (!isestr(fdTaskCpSrc)) {
fdTaskCpSrc = './_taskCpSrc'
}
if (!fsIsFolder(fdTaskCpSrc)) {
fsCreateFolder(fdTaskCpSrc)
}
//fdLog
let fdLog = get(opt, 'fdLog')
if (!isestr(fdLog)) {
fdLog = './_logs'
}
if (!fsIsFolder(fdLog)) {
fsCreateFolder(fdLog)
}
//funDownload
let funDownload = get(opt, 'funDownload')
//funGetCurrent
let funGetCurrent = get(opt, 'funGetCurrent')
//funAdd
let funAdd = get(opt, 'funAdd')
//funModify
let funModify = get(opt, 'funModify')
//funRemove
let funRemove = get(opt, 'funRemove')
//timeToleranceRemove
let timeToleranceRemove = get(opt, 'timeToleranceRemove')
if (!isp0int(timeToleranceRemove)) {
timeToleranceRemove = 0
}
timeToleranceRemove = cdbl(timeToleranceRemove)
//funRemoveDef
let funRemoveDef = async(v) => {
let fd = `${fdResult}/${v.id}`
if (fsIsFolder(fd)) {
fsDeleteFolder(fd)
}
}
if (!isfun(funRemove)) {
funRemove = funRemoveDef
}
//funAddDef
let funAddDef = async(v) => {
let fd = `${fdResult}/${v.id}` //使用v.id做為資料夾名
if (!fsIsFolder(fd)) {
fsCreateFolder(fd)
}
fsCleanFolder(fd)
//readFileSync
let fpSrc = `${fdDwStorageTemp}/${v.id}` //新下載檔案存放於fdDwStorageTemp, v.id為數據檔名
let c = fs.readFileSync(fpSrc, 'utf8')
//parseData
let eq = parseData(c)
//writeFileSync
let fpTar = `${fd}/${eq.id}.json` //使用eq.id做為檔名
fs.writeFileSync(fpTar, JSON.stringify(eq), 'utf8')
}
if (!isfun(funAdd)) {
funAdd = funAddDef
}
//funModifyDef
let funModifyDef = async(v) => {
//複製舊資料夾(含檔案)至fdResultTemp做暫時備份, fdResultTemp會於funAfterStart清空, 於funBeforeEnd刪除
if (true) {
let fdSrc = `${fdResult}/${v.id}`
let fdTar = `${fdResultTemp}/${v.id}`
fsCopyFolder(fdSrc, fdTar)
}
//複製新檔案至fdResult
if (true) {
let fd = `${fdResult}/${v.id}` //使用v.id做為資料夾名
if (!fsIsFolder(fd)) {
fsCreateFolder(fd)
}
fsCleanFolder(fd)
//readFileSync
let fpSrc = `${fdDwStorageTemp}/${v.id}` //新下載檔案存放於fdDwStorageTemp, v.id為數據檔名
let c = fs.readFileSync(fpSrc, 'utf8')
//parseData
let eq = parseData(c)
//writeFileSync
let fpTar = `${fd}/${eq.id}.json` //使用eq.id做為檔名
fs.writeFileSync(fpTar, JSON.stringify(eq), 'utf8')
}
}
if (!isfun(funModify)) {
funModify = funModifyDef
}
let funAfterStart = async() => {
fsCleanFolder(fdResultTemp)
}
let funBeforeEnd = async() => {
fsCleanFolder(fdResultTemp)
}
let optFtp = {
useSimulateFiles,
useExpandOnOldFiles: true, //為增量檔案
fdTagRemove,
fdDwStorageTemp,
fdDwStorage,
fdDwAttime,
fdDwCurrent,
fdResult,
fdTaskCpActualSrc,
fdTaskCpSrc,
fdLog,
funDownload,
funGetCurrent,
funRemove,
funAdd,
funModify,
funAfterStart,
funBeforeEnd,
timeToleranceRemove,
}
let ev = await WDwdataFtp(st, optFtp)
return ev
}
export default WDwdataTweqmp