const fs = require('fs')
const { spawn } = require('child_process')
module.exports = (s,config,lang) => {
    // orphanedVideoCheck : new function
    const checkIfVideoIsOrphaned = (monitor,videosDirectory,filename) => {
        const response = {ok: true}
        return new Promise((resolve,reject) => {
            fs.stat(videosDirectory + filename,(err,stats) => {
                if(!err && stats.size > 10){
                    s.knexQuery({
                        action: "select",
                        columns: "*",
                        table: "Videos",
                        where: [
                            ['ke','=',monitor.ke],
                            ['mid','=',monitor.mid],
                            ['time','=',s.nameToTime(filename)],
                        ],
                        limit: 1
                    },(err,rows) => {
                        if(!err && (!rows || !rows[0])){
                            //row does not exist, create one for video
                            var video = rows[0]
                            s.insertCompletedVideo(monitor,{
                                file : filename
                            },() => {
                                response.status = 2
                                resolve(response)
                            })
                        }else{
                            //row exists, no errors
                            response.status = 1
                            resolve(response)
                        }
                    })
                }else{
                    response.status = 0
                    resolve(response)
                }
            })
        })
    }
    const scanForOrphanedVideos = (monitor,options) => {
        // const options = {
        //     checkMax: 2
        // }
        options = options ? options : {}
        return new Promise((resolve,reject) => {
            const response = {ok: false}
            if(options.forceCheck === true || config.insertOrphans === true){
                if(!options.checkMax){
                    options.checkMax = config.orphanedVideoCheckMax || 2
                }
                let finished = false
                let orphanedFilesCount = 0;
                let videosFound = 0;
                const videosDirectory = s.getVideoDirectory(monitor)
                const tempDirectory = s.getStreamsDirectory(monitor)
                // const findCmd = [videosDirectory].concat(options.flags || ['-maxdepth','1'])
                fs.writeFileSync(
                    tempDirectory + 'orphanCheck.sh',
                    `find "${videosDirectory}" -maxdepth 1 -type f -exec stat -c "%n" {} + | sort -r | head -n ${options.checkMax}`
                );
                let listing = spawn('sh',[tempDirectory + 'orphanCheck.sh'])
                // const onData = options.onData ? options.onData : () => {}
                const onError = options.onError ? options.onError : s.systemLog
                const onExit = () => {
                    try{
                        listing.kill('SIGTERM')
                        fs.unlink(tempDirectory + 'orphanCheck.sh',() => {})
                    }catch(err){
                        s.debugLog(err)
                    }
                    delete(listing)
                }
                const onFinish = () => {
                    if(!finished){
                        finished = true
                        response.ok = true
                        response.orphanedFilesCount = orphanedFilesCount
                        resolve(response)
                        onExit()
                    }
                }
                const processLine = async (filePath) => {
                    let filename = filePath.split('/')
                    filename = `${filename[filename.length - 1]}`.trim()
                    if(filename && filename.indexOf('-') > -1 && filename.indexOf('.') > -1){
                        const { status } = await checkIfVideoIsOrphaned(monitor,videosDirectory,filename)
                        if(status === 2){
                            ++orphanedFilesCount
                        }
                        ++videosFound
                        if(videosFound === options.checkMax){
                            onFinish()
                        }
                    }
                }
                listing.stdout.on('data', async (d) => {
                    const filePathLines = d.toString().split('\n')
                    var i;
                    for (i = 0; i < filePathLines.length; i++) {
                        await processLine(filePathLines[i])
                    }
                })
                listing.stderr.on('data', d=>onError(d.toString()))
                listing.on('close', (code) => {
                    // s.debugLog(`findOrphanedVideos ${monitor.ke} : ${monitor.mid} process exited with code ${code}`);
                    setTimeout(() => {
                        onFinish()
                    },1000)
                });
            }else{
                resolve(response)
            }
        })
    }
    // orphanedVideoCheck : old function
    const orphanedVideoCheck = (monitor,checkMax,callback,forceCheck) => {
        var finish = function(orphanedFilesCount){
            if(callback)callback(orphanedFilesCount)
        }
        if(forceCheck === true || config.insertOrphans === true){
            if(!checkMax){
                checkMax = config.orphanedVideoCheckMax || 2
            }

            var videosDirectory = s.getVideoDirectory(monitor)// + s.formattedTime(video.time) + '.' + video.ext
            fs.readdir(videosDirectory,function(err,files){
                if(files && files.length > 0){
                    var fiveRecentFiles = files.slice(files.length - checkMax,files.length)
                    var completedFile = 0
                    var orphanedFilesCount = 0
                    var fileComplete = function(){
                        ++completedFile
                        if(fiveRecentFiles.length === completedFile){
                            finish(orphanedFilesCount)
                        }
                    }
                    fiveRecentFiles.forEach(function(filename){
                        if(/T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(filename)){
                            fs.stat(videosDirectory + filename,(err,stats) => {
                                if(!err && stats.size > 10){
                                    s.knexQuery({
                                        action: "select",
                                        columns: "*",
                                        table: "Videos",
                                        where: [
                                            ['ke','=',monitor.ke],
                                            ['mid','=',monitor.mid],
                                            ['time','=',s.nameToTime(filename)],
                                        ],
                                        limit: 1
                                    },(err,rows) => {
                                        if(!err && (!rows || !rows[0])){
                                            ++orphanedFilesCount
                                            var video = rows[0]
                                            s.insertCompletedVideo(monitor,{
                                                file : filename
                                            },() => {
                                                fileComplete()
                                            })
                                        }else{
                                            fileComplete()
                                        }
                                    })
                                }
                            })
                        }
                    })
                }else{
                    finish()
                }
            })
        }else{
            finish()
        }
    }
    function cutVideoLength(options){
        return new Promise((resolve,reject) => {
            const response = {ok: false}
            const inputFilePath = options.filePath
            const monitorId = options.mid
            const groupKey = options.ke
            const cutLength = options.cutLength || 10
            const tempDirectory = s.getStreamsDirectory(options)
            let fileExt = inputFilePath.split('.')
            fileExt = fileExt[fileExt.length -1]
            const filename = `${s.gid(10)}.${fileExt}`
            const videoOutPath = `${tempDirectory}`
            const cuttingProcess = spawn(config.ffmpegDir,['-loglevel','warning','-i', inputFilePath, '-c','copy','-t',`${cutLength}`,videoOutPath])
            cuttingProcess.stderr.on('data',(data) => {
                const err = data.toString()
                s.debugLog('cutVideoLength',options,err)
            })
            cuttingProcess.on('close',(data) => {
                fs.stat(videoOutPath,(err) => {
                    if(!err){
                        response.filename = filename
                        response.filePath = videoOutPath
                        setTimeout(() => {
                            s.file('delete',videoOutPath)
                        },1000 * 60 * 3)
                    }else{
                        s.debugLog('cutVideoLength:readFile',options,err)
                    }
                    resolve(response)
                })
            })
        })
    }
    return {
        orphanedVideoCheck: orphanedVideoCheck,
        scanForOrphanedVideos: scanForOrphanedVideos,
        cutVideoLength: cutVideoLength,
    }
}
