require './console'
path = require 'path'
fs = require 'fs'
readline = require 'readline'
child_process = require 'child_process'
server = null
defalutExclude = '.git, logs, .DS_Store, npm-debuge.log, .gitignore'

module.exports = (argv) ->
    if argv[3]
        server = argv[3]

    packageFile = path.join process.cwd(), './package.json'
    startSync packageFile

startSync = (packageFile) ->
    # 检查package.json
    if fs.existsSync packageFile
        syncConfig = JSON.parse(fs.readFileSync packageFile).sync
        if !syncConfig
            console.red '没有配置sync参数，请检查package.json'
            process.exit()

        # 没有通过参数传入服务器的或者传入错误的需要重新输入
        if server is null
            selectServer syncConfig
        else if !syncConfig[server]
            console.red '没有找到对应的服务器，请重新选择'
            selectServer syncConfig
        else
            doSync syncConfig[server]
    else
        console.red '没有找到package.json'
        process.exit()

# 展示服务器列表
selectServer = (syncConfig) ->
    serverList = Object.keys(syncConfig)

    if serverList.length > 0
        console.log '同步配置中的服务器列表:'
        console.log serverList.join('\n')
        getInput(syncConfig)

# 获取选择的服务器列表
getInput = (syncConfig) ->
    rl = readline.createInterface(
        input: process.stdin
        output: process.stdout
    )
    rl.question('请输入要同步的服务器:', (answer) ->
        option = syncConfig[answer]
        if option
            rl.close()
            doSync option
        else
            console.red '输入错误，请重新输入'
            rl.close()
            getInput(syncConfig)
    )

# 开始同步
doSync = (option) ->
    syncCommand = getSyncCommand option

    rl = readline.createInterface(
        input: process.stdin
        output: process.stdout
    )

    question = "是否同步\x1B[34m#{process.cwd()}\x1B[39m " +
        "到 \x1B[34m#{option.host}:#{option.path}\x1B[39m ? [y/n]:"

    rl.question question, (answer) ->
        answer = answer.toLowerCase()
        if answer is 'y' or answer is 'yes'
            startTime = Date.now()
            sync = child_process.exec syncCommand
            error = false

            sync.stdout.on 'data', (data) ->
                console.log data.toString('utf-8')

            sync.stderr.on 'data', (data) ->
                console.red data.toString('utf-8')
                error = true

            sync.on 'error', (err) ->
                console.red err
                error = true

            sync.on 'close', () ->
                if error is false
                    console.green '同步完成，耗时', Date.now() - startTime, 'ms\n'
                else
                    console.red '同步错误，错误信息如上\n'
                rl.close()
        else
            process.exit()

getSyncCommand = (option) ->
    {host, include, exclude, del} = option
    remotePath = option.path

    # 是否删除本地已经不存在的目录和文件
    delOption = if del is true then '--del' else ''
    # 包含文件列表
    includeOption = reJoinClude 'include', include
    # 排除文件列表
    excludeOption = reJoinClude 'exclude', exclude
    # 本地路径
    localPath = process.cwd() + "/"

    syncCommand = ["rsync -rzcv #{delOption}",
        "--timeout=10",
        "--chmod='a=rX,u+w'",
        "--rsync-path='sudo rsync'",
        "#{includeOption}"
        "#{excludeOption}"
        "#{localPath}"
        "#{host}:#{remotePath}"
    ].join ' '

    return syncCommand

reJoinClude = (type, clude) ->
    ret = []

    if type is 'exclude'
        clude = if clude then clude + ',' + defalutExclude else defalutExclude

    if clude
        temp = '--' + type + '='
        cludesFile = clude.split(',')

        for item in cludesFile
            ret.push temp + item.trim()

    return ret.join ' '
