/**
 * Created by anlun on 16/7/16.
 */
var fs = require('fs');
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var del = require('del');
var resourcePath = 'resource';
var releasedPath = "released";
var releasedSrcPath = "released/src";
var releasedResPath = "released/resource";
var replace = require('gulp-replace');
var buildJsConfig = require('./build.json');
var gulpSequence = require('gulp-sequence');
var gulpPngquant = require('gulp-pngquant');
var base64 = require('base64-min');
var isPageToOne = false;
var isHasF2xShare = false;
var shareList = {};
function getFolders(dir) {
    return fs.readdirSync(dir)
        .filter(function (file) {
            return fs.statSync(path.join(dir, file)).isDirectory();
        });
}
gulp.task('delReleased', function () {
    return del(releasedPath);
});
gulp.task('buildJS', function () {
    for (var item in buildJsConfig) {
        var houzui = ".min.js";
        if (isPageToOne) {
            houzui = ".js";
            buildJsConfig[item].unshift("released/resource/" + item + "/" + item + ".res.js");
        }
        gulp.src(buildJsConfig[item])
            .pipe(concat(item + houzui))
            .pipe(uglify())
            .pipe(gulp.dest(releasedSrcPath));
    }
    if (isPageToOne) {
        gulp.src(
            [
                './libs2/zepto.min.js',
                './libs2/annieCore.min.js',
                './libs2/annieUI.min.js',
                './libs2/downloadApp.js',
                './libs2/security.js',
                './released/output.js'])
            .pipe(concat('all.js'))
            .pipe(uglify())
            .pipe(gulp.dest('released'))

        // del('released/libs');
        // del('released/output.js');
    } else {
        gulp.src("src/Main.js")
            .pipe(uglify())
            .pipe(rename("f2xMain.min.js"))
            .pipe(gulp.dest(releasedSrcPath));
    }
});

gulp.task('output', function (params) {
    var date = new Date();
    var shareContent = "";
    if (isHasF2xShare) {
        var shareValue = [];
        for (var item in shareList) {
            shareValue.push("\"" + item + "\"");
        }
        shareContent = "Flash2x._shareSceneList=[" + shareValue.join() + "];"
    }
    // gulp.src("src/Main.js")
    //     .pipe(uglify()).pipe(replace("window.addEventListener", shareContent+"Flash2x._isReleased="+date.getTime()+";window.addEventListener"))
    //     .pipe(rename("f2xMain.min.js"))
    //     .pipe(gulp.dest(releasedSrcPath));

    return gulp.src("output.js")
        .pipe(replace("!function", shareContent + "Flash2x._isReleased=" + date.getTime() + ";F2xExtend = __extends;!function"))
        .pipe(gulp.dest(releasedPath));
})
gulp.task('replaceIndexHtml', function () {
    return gulp.src('index.html')
        .pipe(replace("Main.js", "f2xMain.min.js"))
        .pipe(gulp.dest(releasedPath));
});

gulp.task('copyResource', function () {
    return gulp.src("resource/**/*").pipe(gulp.dest('released/resource'));
});
gulp.task('copyLibs', function () {
    return gulp.src("libs/**/*.js").pipe(gulp.dest('released/libs'));
});
gulp.task('replaceResJson', function () {
    var rex1 = /[\s\r\n\t]+/g;
    var rex2 = /,?\{"src":"src\/.*?","type":"javascript"\}/g;
    var rex3 = /"src":"src\/.+?\.js/;
    var rex4 = /\[,/g;
    var rex5 = /,\]/g;
    var folders = getFolders(resourcePath);
    folders.map(function (folder) {
        gulp.src(path.join(resourcePath, folder, '/*.res.json'))
            .pipe(replace(rex1, ""))
            .pipe(replace(rex2, ""))
            .pipe(replace(rex3, '"src":"src/' + folder + '.min.js'))
            .pipe(replace(rex4, '['))
            .pipe(replace(rex5, ']'))
            .pipe(gulp.dest(releasedResPath + "/" + folder))
    });
});
gulp.task('PNGMin', function () {
    var folders = getFolders(releasedResPath);
    folders.map(function (folder) {
        gulp.src(path.join(resourcePath, folder, '/*.png'))
            .pipe(gulpPngquant())
            .pipe(gulp.dest(releasedResPath + "/" + folder));
    });
});
gulp.task('base64Json', function () {
    isPageToOne = true;
    var content;
    var f2xShare = {};
    var f2xShareContent = "Flash2x.res.f2xShare={};";
    for (var item in buildJsConfig) {
        var resourceJson = require("./released/resource/" + item + "/" + item + ".res.json");
        var resContent = [];
        for (var i = resourceJson.length - 1; i >= 0; i--) {
            if (resourceJson[i].type == "javascript") {
                resourceJson.splice(i, 1);
            } else {
                var url = resourceJson[i].src;
                var index = url.indexOf("?");
                if (index > 0) {
                    url = url.substr(0, index);
                }
                if (url.indexOf(".json") > 0) {
                    var jsonData = require("./released/" + url);
                    resContent.push(resourceJson[i].id + ":\'" + JSON.stringify(jsonData, null, "") + "\'");
                } else {
                    var head;
                    if (url.indexOf(".jpg") > 0) {
                        head = "data:image/jpg;base64,";
                    } else if (url.indexOf(".png") > 0) {
                        head = "data:image/png;base64,";
                    } else if (url.indexOf(".mp3") > 0) {
                        head = "data:audio/mp3;base64,";
                    }
                    if (url.indexOf("f2xShare") > 0) {
                        shareList[item] = true;
                        isHasF2xShare = true;
                        if (!f2xShare[resourceJson[i].id]) {
                            f2xShare[resourceJson[i].id] = true;
                            var base64Res = base64.encodeFile("released/" + url);
                            f2xShareContent += "Flash2x.res.f2xShare." + resourceJson[i].id + "=\"" + head + base64Res + "\";";
                        }
                        resContent.push(resourceJson[i].id + ":Flash2x.res.f2xShare." + resourceJson[i].id);
                    } else {
                        var base64Res = base64.encodeFile("released/" + url);
                        resContent.push(resourceJson[i].id + ":\"" + head + base64Res + "\"");
                    }
                }
            }
        }
        content = "Flash2x." + item + "Res={" + resContent.join() + "};";
        fs.writeFile(path.join(__dirname, "/released/resource/" + item + "/" + item + ".res.js"), content, "utf8", function (err) {
        });
    }
    if (isHasF2xShare) {
        fs.writeFile(path.join(__dirname, "/released/src/f2xShare.js"), f2xShareContent, "utf8", function (err) {
        });
    }
});
gulp.task('clear', function () {
    setTimeout(function () {
        del("released/resource/f2xShare");
        for (var item in buildJsConfig) {
            del("released/resource/" + item);
            del("released/src/" + item + ".min.js");
        }
    }, 100);
});
gulp.task('default', gulpSequence('delReleased', 'copyResource', 'copyLibs', 'replaceIndexHtml', 'replaceResJson', 'PNGMin', 'buildJS'));
// gulp.task('packToOne', gulpSequence('output'));
gulp.task('packToOne', gulpSequence('base64Json', 'output', 'buildJS', 'clear'));




////

/*
 * @Author: 周成
 * @Date: 2018-01-24 14:32:14
 * @Last Modified by: 周成
 * @Last Modified time: 2018-01-29 20:58:10
 */

const co = require('co');
const OSS = require('ali-oss');

const chalk = require('chalk');
const ProgressBar = require('progress');

class TuiaAutoUpload {
    constructor(props, type) {
        this.type = type;
        const defaultOptions = {
            dir: undefined,
            originDir: undefined
        }
        this.options = Object.assign({}, defaultOptions, props);
        if (!this.options.dir || !this.options.originDir) {
            console.log(chalk.red('缺少参数，初始化失败'))
            return;
        }
        this.init();
    }
    init() {
        var _this = this;
        this.client = new OSS({
            region: 'oss-cn-hangzhou',
            accessKeyId: 'LTAIdGi1IOap7fkF',
            accessKeySecret: 'SKrOOp6EVtDGEV47yn0t2h97gyNioQ',
            bucket: _this.type === 'prod' ? 'duiba' : 'daily-duiba'
        });
        this.bar = new ProgressBar(chalk.yellow(`  文件上传中 [:bar] :current/${this.files().length} :percent :elapseds`), {
            complete: '●',
            incomplete: '○',
            width: 20,
            total: this.files().length,
            callback: () => {
                console.log(chalk.green('\n  All complete.'));
                console.log(chalk.blue(`\n  本次队列文件共${this.files().length}个，已存在文件${this.existFiles}个，上传文件${this.uploadFiles}个，上传失败文件${this.errorFiles}个\n`));
            }
        })
        return this;
    }
    files() {
        var _this = this;
        if (this._files) return this._files;
        this._files = [];

        /**
         * 文件遍历方法
         * @param filePath 需要遍历的文件路径
         */
        function fileDisplay(filePath) {
            //根据文件路径读取文件，返回文件列表
            var files = fs.readdirSync(filePath);
            files.forEach(function (filename) {
                //获取当前文件的绝对路径
                var filedir = path.join(filePath, filename);
                //根据文件路径获取文件信息，返回一个fs.Stats对象
                var stats = fs.statSync(filedir);
                var isFile = stats.isFile();//是文件
                var isDir = stats.isDirectory();//是文件夹
                if (isFile) {
                    var sep = '/';
                    if ('win32' == process.platform)
                        sep = '\\';
                    var newDirArr = filedir.split(sep);
                    newDirArr.shift();
                    _this._files.push(newDirArr.join('/'));
                }
                if (isDir) {
                    fileDisplay(filedir);//递归，如果是文件夹，就继续遍历该文件夹下面的文件
                }
            });

        }

        //调用文件遍历方法
        fileDisplay(this.options.dir);
        return this._files;
    }
    start() {
        this.files().map((file, index) => {
            let _this = this;
            const path1 = path.join(__dirname,'released', file);
            let originFile;
            this.existFiles = 0;
            this.uploadFiles = 0;
            this.errorFiles = 0;
            co(function* () {
                const originPath = `${_this.options.originDir}${file}`;
                try {
                    originFile = yield _this.client.head(originPath);
                } catch (error) {
                    originFile = error;
                }
                if (_this.type === 'prod') {
                    if (originFile.status === 404) {
                        yield _this.client.put(originPath, path1);
                        _this.uploadFiles += 1;
                    } else {
                        _this.existFiles += 1;
                    }
                } else if (_this.type === 'dev') {
                    if (originFile.status === 404 || originFile.status === 200) {
                        _this.existFiles += 1;
                    }
                    yield _this.client.put(originPath, path1, {
                        headers: {
                            'Cache-Control': 'no-cache'
                        }
                    })
                    _this.uploadFiles += 1;
                }
                _this.bar.tick();
            }).catch(function (err) {
                _this.errorFiles += 1;
                console.log(err);
            });
        });
    }
}


gulp.task('publish-dev', function () {
    const configFileName = 'project.json';
    if (!fs.existsSync(configFileName)) {
        throw new Error(`${configFileName}不存在.`)
    }
    let config = fs.readFileSync('project.json');
    config = JSON.parse(config + '');
    if (!config.type) {
        throw new Error(`${configFileName}的type不存在.`)
    }

    if (!config.name) {
        throw new Error(`${configFileName}的name不存在.`)
    }

    const now = new Date();
    const version = Math.round(now.getTime() / 1000);
    console.log(`版本号：${version}`)

    const autoupload = new TuiaAutoUpload({
        dir: './released/',
        // dir: path.join(__dirname, './released/'),
        originDir: `/db_games/${config.type}/${config.name}/${version}/`
    }, "dev")

    autoupload.start()

});

gulp.task('publish-prod', function () {
    const configFileName = 'project.json';
    if (!fs.existsSync(configFileName)) {
        throw new Error(`${configFileName}不存在.`)
    }
    let config = fs.readFileSync('project.json');
    config = JSON.parse(config + '');
    if (!config.type) {
        throw new Error(`${configFileName}的type不存在.`)
    }

    if (!config.name) {
        throw new Error(`${configFileName}的name不存在.`)
    }

    const now = new Date();
    const version = Math.round(now.getTime() / 1000);
    console.log(`版本号：${version}`)

    const autoupload = new TuiaAutoUpload({
        dir: './released/',
        // dir: path.join(__dirname, './released/'),
        originDir: `/db_games/${config.type}/${config.name}/${version}/`
    }, "prod")

    autoupload.start()
});