require './console'
fs = require 'fs'
path = require 'path'
spawn = require('child_process').spawn
exec = require('child_process').exec
argv = require('optimist').argv

currentProcess = null

cwd = process.cwd()
logsDir = path.join(cwd, './logs')
startFile = path.join(cwd, 'bin/start')
projectDir = path.join(cwd, './')

excludeExtname = []
excludeDirectory = ['.git', 'logs']
excludeFile = []

if !fs.existsSync(logsDir)
    fs.mkdirSync(logsDir)

module.exports = () ->

    packageConfig = fs.readFileSync path.join(cwd, './package.json')

    # 排除的目录
    excludeConfig = JSON.parse(packageConfig.toString()).watch
    if excludeConfig and excludeConfig.excludeFolder
        excludeDirectory = excludeDirectory.concat(excludeConfig.excludeFolder)

    # 排除的后缀
    if excludeConfig and excludeConfig.excludeFileExt
        excludeExtname = excludeExtname.concat(excludeConfig.excludeFileExt)

    # 排除的文件
    if excludeConfig and excludeConfig.excludeFile
        excludeFile = excludeFile.concat(excludeConfig.excludeFile)


    console.log "不被监视的目录 #{excludeDirectory}"
    excludeExtname.length > 0 and console.log "不被监视的文件后缀 #{excludeExtname}"
    excludeFile.length > 0 and console.log "不被监视的文件 #{excludeFile}"

    bindEvent()
    startServer()
    watchFile()

startServer = () ->
    evn = 'development'
    if argv.e isnt undefined and argv.e isnt true
        evn = argv.e
    console.log "环境变量#{evn}"
    setEnv = 'NODE_ENV=' + evn
    debug = ''

    if process.platform is "win32"
        setEnv = 'set NODE_ENV=' + evn + '&& '

    if argv.debug is true
        debug = '--debug'

    if typeof argv.debug is 'number'
        debug = '--debug=' + argv.debug

    if argv['debug-brk'] is true
        debug = '--debug-brk'

    if typeof argv['debug-brk'] is 'number'
        debug = '--debug-brk=' + argv['debug-brk']

    command = "#{setEnv} node --harmony #{debug} #{startFile} -l #{logsDir}"

    start = exec(command)

    console.log('开始启动，日志位于:', logsDir)

    start.stdout.on('data', (data) ->
        console.log(data.toString().replace('\n', ''))
    )

    start.stderr.on('data', (data) ->
        console.log(data.toString().replace('\n', ''))
    )

    currentProcess = start


watchFile = () ->
    walk = (filepath) ->

        files = fs.readdirSync(filepath)
        files.forEach((item) ->
            tmpPath = path.join(filepath, item)

            if fs.existsSync(tmpPath)
                stats = fs.statSync(tmpPath)

                if stats.isDirectory()
                    if excludeDirectory.indexOf(item) < 0
                        walk(tmpPath)

                else
                    extname = path.extname tmpPath
                    if excludeExtname.indexOf(extname) < 0 and excludeFile.indexOf(item) < 0
                        fs.watchFile(tmpPath, {
                            persistent: true
                            interval: 1000
                        }, (oldStat, newStat) ->
                            if newStat.mtime.getTime() isnt oldStat.mtime.getTime()
                                restartServer()
                        )
        )
    walk(projectDir)


restartServer = () ->
    console.log('开始重启')
    killProcess(currentProcess.pid, () ->
        startServer()
    )

killProcess = (pid, callback) ->
    if process.platform is "win32"
        exec('taskkill /F /T /PID ' + pid, () ->
            callback and callback()
        )
    else
        process.kill(pid)
        callback and callback()

bindEvent = () ->
    if process.platform is "win32"
        rl = require("readline").createInterface({
            input: process.stdin,
            output: process.stdout
        })

        rl.on "SIGINT", () ->
            process.emit("SIGINT")

    process.on("SIGINT", () ->
        killProcess(currentProcess.pid, () ->
            process.exit()
        )
    )

    process.on("exit", () ->
        console.log('工作进程退出, pid:', currentProcess.pid)
    )
