var fs = require('fs'),
    file = require('../../../../lib/file'),
    mockInjector = require('../../../mock_injector'),
    testResource = require('../../../test_resource'),
    generateStructure = require('../../../../ci/worker/generate_structure');

exports.setUp = function (done) {
    process.env.CI_LOG_DISABLED = true;
    mockInjector.restoreAll();
    done();
};
exports.tearDown = function (done) {
    process.env.CI_LOG_DISABLED = false;
    mockInjector.restoreAll();
    done();
};

exports['Flatten data.'] = function (test) {
    var data = generateStructure._flatten({
        ci: { bin: {}, worker: {} },
        lib: {
            '_prototype.js': {
                __serializable: true,
                _tmpl: 'tmpl/_prototype.js.hbs'
            },
            index: {
                __serializable: true,
                _tmpl: 'tmpl/index.js.hbs'
            }
        },
        test: { unit_tests: {} },
        'README.md': { __serializable: true,
            _tmpl: 'tmpl/md/README.md.hbs' }
    });
    test.ok(data);
    test.done();

};

exports['Resolve creator.'] = function (test) {
    test.ok(generateStructure._resolveCreator('file'));
    test.ok(generateStructure._resolveCreator('symlink'));
    test.ok(generateStructure._resolveCreator());
    test.done();
};

exports['Create a file.'] = function (test) {
    var filename = testResource.resolveWorkFile('work_build_structure_file.txt');
    generateStructure._createFile({
        __path: filename,
        _tmpl: testResource.resolveMockFile('mock-template.hbs')
    })(function (err) {
        test.ifError(err);
        fs.exists(filename, function (exists) {
            test.ok(exists);
            test.done();
        });
    });
};
exports['Create a directory.'] = function (test) {
    var dirname = testResource.resolveWorkFile('work_build_structure_dir/foo/bar');
    generateStructure._createDir({
        __path: dirname
    })(function (err) {
        test.ifError(err);
        test.done();
    });
};
exports['Create a symlink.'] = function (test) {
    var linkName = testResource.resolveWorkFile('work_build_structure_link');
    generateStructure._createSymlink({
        __path: linkName,
        _src: __filename
    })(function (err) {
        test.ifError(err);
        test.done();
    })
};

exports['Write file p.'] = function (test) {
    var workDir = testResource.resolveWorkFile('work_generate_structure_create_file_p');
    generateStructure._writeFileP(workDir + '/foo/bar/baz', 'foo_bar_baz', function (err) {
        test.ifError(err);
        test.done();
    });
};
exports['Create dir.'] = function (test) {
    var workDir = testResource.resolveWorkFile('work_generate_structure_create_dir');
    generateStructure._createDir({
        __path: workDir
    })(function (err) {
        test.ifError(err);
        generateStructure._createDir({
            __path: workDir
        })(function (err) {
            test.ifError(err);
            test.done();
        });
    });
};

exports['Handle errors.'] = function (test) {
    mockInjector.inject(file, 'forceUnlink', function (filename, callback) {
        callback(new Error('mock force unlink error.'));
    });
    generateStructure._createSymlink({__path: 'foo'})(function (err) {
        mockInjector.restore();
        test.ok(err);
        test.done();
    });
};

exports['Generate a structures.'] = function (test) {
    mockInjector.inject(generateStructure, '_resolveCreator', function () {
        return function (data) {
            return function (callback) {
                callback();
            }
        };
    });
    generateStructure({
        data: {}
    }, function (err) {
        test.ifError(err);
        mockInjector.restore();
        test.done();
    });
};


exports['Create file write .'] = function (test) {
    var filename = testResource.resolveWorkFile('work_generate_structure_write.txt');
    generateStructure._createFile._write(filename, "foo", '777', function (err) {
        test.ifError(err);
        generateStructure._createFile._write(filename, "foo", null, function (err) {
            test.ifError(err);
            mockInjector.inject(generateStructure, '_writeFileP', function (f, c, callback) {
                callback(new Error('mock error'));
            });
            generateStructure._createFile._write(filename, "foo", null, function (err) {
                test.ok(err);
                test.done();
            });
        });
    });
};

exports['Handle error on create symlink.'] = function (test) {
    var _createSymlink = generateStructure._createSymlink({
        __path: testResource.resolveWorkFile('work__createSymlink')
    });
    mockInjector.inject(file, 'mkdirP', function (dirname, callback) {
        callback(new Error('mock error'));
    });
    _createSymlink(function (err) {
        mockInjector.restore();
        test.ok(err);
        mockInjector.inject(file, 'forceUnlink', function (dirname, callback) {
            callback(new Error('mock error'));
        });
        _createSymlink(function (err) {
            mockInjector.restore();
            test.ok(err);
            test.done();
        });
    });
};
