
let fs = require("fs")
let path = require("path")
let concat = require('concat-files')
let uploadDir = "uploads"
let formidable = require("formidable")
var execSync = require('child_process').execSync;
var request = require('request');


// let asyncBusboy = require("async-busboy")
// 获取文件Chunk列表
async function getChunkList(filePath, folderPath, callback) {
    let isFileExit = await isExist(filePath)
    let result = {}
    // 如果文件(文件名, 如:node-v7.7.4.pkg)已在存在, 不用再继续上传, 真接秒传
    if (isFileExit) {
        result = {
            stat: 1,
            file: {
                isExist: true,
                name: filePath
            },
            desc: "file is exist"
        }
    } else {
        let isFolderExist = await isExist(folderPath)
        console.log(folderPath)
        // 如果文件夹(md5值后的文件)存在, 就获取已经上传的块
        let fileList = []
        if (isFolderExist) {
            fileList = await listDir(folderPath)
        }
        result = {
            stat: 1,
            chunkList: fileList,
            desc: "folder list"
        }
    }
    callback(result)
}

// 文件或文件夹是否存在
function isExist(filePath) {
    return new Promise((resolve, reject) => {
        fs.stat(filePath, (err, stats) => {
            // 文件不存在
            if (err && err.code === 'ENOENT') {
                resolve(false)
            } else {
                resolve(true)
            }
        })
    })
}

// 列出文件夹下所有文件
function listDir(path) {
    return new Promise((resolve, reject) => {
        fs.readdir(path, (err, data) => {
            // 把mac系统下的临时文件去掉
            if (data && data.length > 0 && data[0] === '.DS_Store') {
                data.splice(0, 1)
            }
            resolve(data)
        })
    })
}
// 合并文件
async function mergeFiles(srcDir, targetDir, newFileName, size) {
    let targetStream = fs.createWriteStream(path.join(targetDir, newFileName))
    let fileArr = await listDir(srcDir)
    // 把文件名加上文件夹的前缀
    for (let i = 0; i < fileArr.length; i++) {
        fileArr[i] = srcDir + "/" + fileArr[i]
    }
    concat(fileArr, path.join(targetDir, newFileName), () => {
        var re_str = execSync('rm -rf ' + srcDir);
        console.log('Merge Success@!')
    })
}

exports.get_file_list = async function(){
    await this.bindDefault();
    fileList = await listDir("./uploads");
    this.body = {
        list: fileList
    }
    return
}
exports.get_file_list.__method__ = "ALL";


exports.check_file = async function () {
    await this.bindDefault();
    let _this = this;
    let query = this.query
    let fileName = query.fileName
    let fileMd5Value = query.fileMd5Value
    // 获取文件Chunk列表
    getChunkList(path.join(uploadDir, fileName), path.join(uploadDir, fileMd5Value), (data) => {
        _this.body = data
    })
	return
}
exports.check_file.__method__ = 'ALL';

exports.check_chunk = async function () {
    await this.bindDefault();
    let query = this.query
    let chunkIndex = query.index
    let md5 = query.md5
    let _this = this;
    fs.stat(path.join(uploadDir, md5, chunkIndex), (err, stats) => {
        if (stats) {
            _this.body = {
                "stat": 1,
                "exit": true,
                "desc": "Exit 1"
            }
        } else {
            _this.body = {
                "stat": 1,
                "exit": false,
                "desc": "Exit 0"
            }
        }
    })
	return
}
exports.check_chunk.__method__ = 'GET';

exports.merge = async function () {
    await this.bindDefault();
    let query = this.query
    let md5 = query.md5
    let size = query.size
    let fileName = query.fileName
    console.log(md5);
    console.log(fileName);
    mergeFiles(path.join(uploadDir, md5), uploadDir, fileName, size)
    this.body = {
        "stat": 1
    }
	return
}
exports.merge.__method__ = 'ALL';

exports.upload = async function () {
    await this.bindDefault();
    let _this = this;
    var form = new formidable.IncomingForm({
        uploadDir: "tmp"
    })
    function folderIsExit(folder) {
        let promise = new Promise((resolve, reject) => {
            fs.stat(folder, (err, stats) => {
                // 文件夹不存在
                if (err && err.code === 'ENOENT') {
                    fs.mkdir(folder, () => {
                        resolve()
                    })
                } else {
                    resolve()
                }
            })
        })
        return promise
    }
    // 把文件从一个目录拷贝到别一个目录
    function copyFile(src, dest) {
        console.log(src)
        console.log(dest)
        let promise = new Promise((resolve, reject) => {
            fs.rename(src, dest, (err) => {
                if (err) {
                    reject(err)
                } else {
                    resolve('copy file:' + dest + ' success!')
                }
            })
        })
        return promise
    }
    async function parseCallBack(err, fields, file){
        let index = fields.index
        let total = fields.total
        let fileMd5Value = fields.fileMd5Value
        let folder = path.join('uploads', fileMd5Value)
        folderIsExit(folder).then(() => {
            let destFile = path.join(folder, fields.index)
            copyFile(file.data.path, destFile).then((successLog) => {
                console.log("文件拷贝成功")
                // _this.body = {
                //     "stat": 1,
                //     "desc": index
                // }
            }, (errorLog) => {
                console.log("文件拷贝失败")
                // _this.body = {
                //     "stat": 0,
                //     "desc": "Error"
                // }
            })
        })
    }
    await form.parse(this.req,parseCallBack)
    this.body = { success: true }
	return
}
exports.upload.__method__ = 'ALL';