/**
 * Expand data seed files.
 * @function task.worker.expandDataSeedFiles
 * @param {object} config - Task configuration
 * @param {string} config.srcDir - Seed file directory name.
 * @param {string} config.destDir - Destination directory.
 * @param {string} config.patternFiles - Pattern data file names.
 * @param {function} callback - Callback when done. Lang as key, glob file name as value.
 * @example expandDataSeedFiles({
 *      srcDir: 'test/data/seeds',
 *      dataPatternFiles: {
 *         en: 'test/data/patterns/en/*.json',
 *         ja: 'test/data/patterns/ja/*.json'
 *      },
 *      destDir:'test/data/$dev/expanded'
 * });
 * @author Taka Okunishi
 *
 */
var _prototype = require('./_prototype'),
    _convertDirectory = _prototype._convertDirectory,
    debug = require('./_debug'),
    lib = require('../../lib'),
    _evaluateSeedEntry = require('./_evaluate_seed_entry'),
    path = require('path'),
    file = lib.file,
    object = lib.object,
    string = lib.string,
    random = lib.random,
    date = lib.date;

exports = module.exports = function (config, callback) {
    exports._loadPatterns(config.patternFiles, function (err, patterns) {
        if (err) {
            callback(err);
            return;
        }
        _convertDirectory({
            srcDir: config.srcDir,
            destDir: config.destDir,
            pattern: '**/*-seed.js',
            ignore: '**/_*.js',
            fileNameConverter: function (filename) {
                var extname = path.extname(filename),
                    basename = path.basename(filename, extname).replace(/\-data-seed$/, '-data-expanded'),
                    dirname = path.dirname(filename);
                return path.join(dirname, basename + '-data.json');
            },
            fileContentConverter: function (src, dest, callback) {
                var entries = require(src).entries || [],
                    result = [];
                [].concat(entries).forEach(function (entry) {
                    var lang = entry._lang || 'en',
                        repeat = entry._repeat || 1;
                    delete entry._repeat;
                    delete entry._lang;
                    for (var i = 0; i < repeat; i++) {
                        var data = exports._choicePattern(patterns[lang]),
                            scope = exports._scope(data, result.length);
                        result.push(_evaluateSeedEntry(entry, scope));
                    }
                });
                var content = JSON.stringify(result, null, 4);
                file.writeReadonlyFile(dest, content, function (err) {
                    if (!err) {
                        debug.didCreateFile(dest);
                    }
                    callback(err);
                });
            }
        }, function (err) {
            callback(err);
        });
    });
};

exports._scope = function (data, i) {
    var scope = object.deepCopy(data, {});
    scope.Date = date.FormattableDate;
    scope.now = new scope.Date;
    object.deepCopy(string, scope);
    object.deepCopy(random, scope);
    scope.index = scope.i = i;
    return scope;
};


exports._loadPatterns = function (fileData, callback) {
    var result = {};
    var langs = Object.keys(fileData);
    require('async').series(
        langs
            .map(function (lang) {
                return {
                    lang: lang,
                    filename: fileData[lang]
                }
            })
            .map(function (data) {
                return function (callback) {
                    file.expandGlob(data.filename, function (err, filenames) {
                        if (err) {
                            callback(err);
                            return;
                        }
                        var lang = data.lang;
                        if (!result[lang]) result[lang] = [];
                        filenames.forEach(function (filename) {
                            var extname = path.extname(filename),
                                basename = path.basename(filename, extname);
                            result[lang].push({
                                keys: basename.split('&').map(function (name) {
                                    return string.camelize(name)
                                }),
                                values: require(filename)
                            });
                        });
                        callback(null);
                    });
                };
            }),
        function (err) {
            callback(err, result);
        }
    )
};

exports._choicePattern = function (data) {
    var result = {};
    data.forEach(function (data) {
        var keys = data.keys,
            values = [].concat(random.choice.apply(random, data.values));
        for (var i = 0; i < keys.length; i++) {
            result[keys[i]] = values[i];
        }
    });
    return result;
};