// const shell = require('shelljs')
const proc = require('child_process')
const path = require('path')
const fs = require('fs')

var PG_CTL_EXE = "pg_ctl"
var PG_INIT_EXE = "initdb"
if(process.platform == 'win32'){
    PG_CTL_EXE = "pg_ctl.exe"
    PG_INIT_EXE = "initdb.exe"
}

// 获取EXE执行当前目录
var OWN_DIR = process.env.PORTABLE_EXECUTABLE_DIR || process.env.OWD || process.cwd() || __dirname
// 设置PG二进制程序目录
var CWD = path.join(OWN_DIR,"node_modules/@embedded-postgres/linux-x64/native/bin/")
if(process.platform == 'win32'){
    CWD = path.join(OWN_DIR,"node_modules/@embedded-postgres/windows-x64/native/bin/")
}
// 可执行文件
var pgCtlExe = path.join(CWD,PG_CTL_EXE)
var pgInitExe = path.join(CWD,PG_INIT_EXE)
var DBDataDir


/**
 * 
 * @param {*} dbconfig 
 * @desc
 * npm i -D @embedded-postgres/linux-x64 -f
 * npm i -D @embedded-postgres/windows-x64 -f
 * cp -rf node_modules/@embedded-postgres/linux-x64/native/* bin/pg/bin/
 * cp -rf node_modules/@embedded-postgres/windows-x64/native/* bin/pg/bin/
 */
async function PostgreSQLKeep(dbconfig){
    DBDataDir = path.join(OWN_DIR,dbconfig.dbpath)

    console.log("PostgreSQLKeep",dbconfig)
    // pgStop(dbconfig)
    let start = async ()=>{
        await InitAndStartDB(dbconfig)
        if(pgStatus(dbconfig)!="running"){
            console.log("DB Service Relaunching...")
            await wait(1000);
            await start();
        }
    }

    await start();
    return
}
function wait(delay){
    return new Promise((resolve)=>{
        setTimeout(() => {
            resolve(true)
        }, delay);
    })
}
async function InitAndStartDB(dbconfig){
    let status = pgStatus(dbconfig)
    console.log("status",status)
    if(status=="noinit"){
        let initRes = ""
        // ./initdb.exe -D "C:\web3\psqlite\data\db\minerdb" -U postgres -A trust
        try{initRes = proc.execSync(`${pgInitExe} -D "${DBDataDir}" -U ${dbconfig.username} -A trust`)}catch(err1){}
        console.log("initRes",initRes)
        await pgRestart(dbconfig)
        return
    }
    if(status=="nostart"){
        await pgRestart(dbconfig)
        return
    }

    return
}

function pgRestart(dbconfig){
    console.log("pgRestart")
    let startRes = ""
    let cmd = `${pgCtlExe}`
    let args = [`restart`,`-D`, `"${DBDataDir}"`, `-U`, `${dbconfig.username}`, `-o`, `"-p ${dbconfig.port}"`]
    console.log(cmd,args.join(" "))
    return new Promise(resolve=>{
        let pgstart
        let options = {
            detached:true,
            shell:true,
            // stdio:"ignore",
            windowsHide:true
        }
        if(process.platform == 'win32'){ // start 从窗口打开，脱离当前程序 /min 新窗口默认最小化
            // pgstart = proc.spawn("cmd",["/c","",cmd,...args],options);
            pgstart = proc.spawn("start",["/min",cmd,...args],options);
        }else{
            pgstart = proc.spawn(cmd,args,options);
        }
        pgstart.unref();
        setTimeout(() => {
            resolve(true)
        }, 5000);
        // console.log(pgstart)
        pgstart.stdout.on("data",(data)=>{
            console.log("stdout",data.toString())
            resolve(true)
        })
        pgstart.stderr.on("data",(data)=>{
            console.error("stdout",data)
            resolve(true)
        })
        pgstart.on("close",(code)=>{
            console.error("close",code)
            resolve(true)
        })
        
    })
}

function pgStop(dbconfig){
    let stopRes = ""
    try{stopRes = proc.execSync(`${pgCtlExe} stop -D "${DBDataDir}" -U ${dbconfig.username}`)}catch(err1){
        console.log(err1)
    }
    console.log("stopRes",stopRes)
    return
}

function pgStatus(dbconfig){
    // ./pg_ctl.exe status -D "C:\web3\psqlite\data\db\minerdb" -U postgres

    if(!fs.existsSync(DBDataDir)){
        console.log("DB Service Initializing...")
        return "noinit"
    }
    let statusRes = ""
    let cmd = `${pgCtlExe} status -D "${DBDataDir}" -U ${dbconfig.username}`
    // console.log(cmd)
    try{statusRes = proc.execSync(cmd)}catch(err1){
        // console.log(err1)
        if(err1.status == 3){
            return "nostart"
        }
    }
    console.log("statusRes",statusRes)
    if(statusRes?.indexOf("PID")){
        return "running"
    }
    return "nostart"
}
module.exports.PostgreSQLKeep = PostgreSQLKeep