const shell = require('shelljs')

// 将同步函数转换成Promise
function wrapper (fn) {
    return function () {
        const args = arguments
        return new Promise(function (resolve, reject) {
            const result = fn.apply(this, args)
            if (result.code === 0) {
                resolve(result)
            } else {
                reject({ code: result.code, type: 'shell', message: result.stderr })
            }
        })
    }
}

function execWrapper (fn) {
    return function (command, options) {
        if (options.outputFilter) {
            options.silent = true
        }
        return new Promise(function (resolve, reject) {
            console.debug('exec:', command)
            const child = fn(command, { ...(options || {}), async: true }, (code, stdout, stderr) => {
                if (code === 0) {
                    resolve({ code, stdout, stderr })
                } else {
                    reject({ code, type: 'shell', message: stderr })
                }
            })
            if (options.outputFilter) {
                child.stdout.on('data', options.outputFilter.bind(null, 'stdout'))
                child.stderr.on('data', options.outputFilter.bind(null, 'stderr'))
            }
        })
    }
}

const functions = {}
Object.keys(shell).forEach(key => {
    if (/^[a-z]+$/.test(key) && typeof shell[key] === 'function') {
        switch (key) {
            case 'exec':
                functions[key] = execWrapper(shell[key])
                break
            default:
                functions[key] = wrapper(shell[key])
        }
    }
})

module.exports = functions
