/**
 * Generate instruments for coverage report.
 * @function ci.worker.generateInstruments
 * @param {object} config - Task configuration.
 * @param {string} config.srcDir - Source directory.
 * @param {string} config.testDir - Test files directory.
 * @param {string} config.instrumentsDir - Instruments root directory name.
 * @param {function} callback - Callback when done.
 * @author Taka Okunishi
 */
var path = require('path'),
    lib = require('../../lib'),
    file = lib.file,
    debug = require('./_debug'),
    copyFile = file.copyFile,
    copyDir = file.copyDir,
    apeman = require('apeman'),
    prepareCleanDir = file.prepareCleanDir;

exports = module.exports = function (config, callback) {
    var baseDir = apeman.currentProject.basedir,
        srcDir = exports._resolveAll(config.srcDir),
        testDir = exports._resolveAll(config.testDir),
        filesToCopy = exports._resolveAll(config.filesToCopy),
        instrumentsDir = path.resolve(baseDir, config.instrumentsDir);
    file.prepareCleanDir(instrumentsDir, function () {
        require('async').series(
            srcDir.map(function (srcDir) {
                var destDir = path.resolve(instrumentsDir, path.relative(baseDir, srcDir));
                return function (callback) {
                    prepareCleanDir(destDir, function (err) {
                        if (err) {
                            callback(err);
                            return;
                        }
                        var here = process.cwd();
                        process.chdir(baseDir);
                        require('jscoverage').processFile(
                            path.relative(baseDir, srcDir),
                            path.relative(baseDir, destDir),
                            [ /^_svn/], {});
                        process.chdir(here);
                        callback();
                    });
                };
            })
                .concat(
                testDir.map(function (srcDir) {
                    return function (callback) {
                        var destDir = path.resolve(instrumentsDir, path.relative(baseDir, srcDir));
                        copyDir(
                            srcDir,
                            destDir,
                            function (err) {
                                if (!err) {
                                    debug.didCopyDir(srcDir, destDir);
                                }
                                callback(err);
                            }
                        );
                    };
                })
            )
                .concat(
                filesToCopy.map(function (fileToCopy) {
                    return function (callback) {
                        var dest = path.resolve(instrumentsDir, path.relative(baseDir, fileToCopy));
                        file.mkdirP(path.dirname(dest), function (err) {
                            if (err) {
                                callback(err);
                                return;
                            }

                            copyFile(
                                fileToCopy,
                                dest,
                                function (err) {
                                    if (!err) {
                                        debug.didCopyFile(fileToCopy, dest);
                                    }
                                    callback(err);
                                }
                            );
                        });
                    }
                })
            ),
            function (err) {
                callback(err);
            }
        );
    });
};

exports._resolveAll = function (filename) {
    return [].concat(filename || []).map(function (filename) {
        return path.resolve(filename);
    });
};