/**
 * @link http://mochajs.org/
 * @link https://www.npmjs.com/package/assert
 * @link https://github.com/defunctzombie/commonjs-assert
 */

var assert = require('assert')
var path = require('path')
var _extend = require('extend')

/** @link https://github.com/arturadib/shelljs */
require('shelljs/global')


/**
 * @var {Object} Logger
 */
var Logger = require('../build/lib/logger')

process.env.JUPITER_CONFIG_EXT = 'json'

/**
 * @var {Object} VirtualManager
 */
var VirtualManager = require('../build/lib/VirtualManager/VirtualManager')

var logger = new Logger()

describe('VirtualManager\\VirtualManager', function(){
    describe('#constructor()', function(){
        it('should instantiate vm object', function(){
            rm('-rf', '/tmp/test1')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test1'
            })
            assert.notEqual(null, vm)
            assert.notEqual(null, vm.config)
            assert.equal('vagrant', vm.config.getType())
            assert.equal('/tmp/test1/config.json', vm.configPath)
            assert.equal(true, require('fs').existsSync('/tmp/test1/config.json'))
            rm('-rf', '/tmp/test1')
        })
    })
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    describe('#init()', function(){
        it('should init a virtual machine from #constructor() options ', function(done){
            rm('-rf', '/tmp/test10')
            var vm = new VirtualManager({
                'config': { 'name' : 'test10' },
                'logger': logger,
                'p': '/tmp/test10'
            })
            vm.init().then(function(){
                assert.equal('test10', vm.config.config.vm[0].name)
                rm('-rf', '/tmp/test10')
                done()
            }, done)
        })
        it('should init a virtual machine from #init() argument', function(done){
            rm('-rf', '/tmp/test20')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test20'
            })
            vm.init({ 'name' : 'test20' }).then(function(){
                assert.equal('test20', vm.config.config.vm[0].name)
                rm('-rf', '/tmp/test20')
                done()
            }, done)
        })
        it('should init multiple virtual machines from #init() argument', function(done){
            rm('-rf', '/tmp/test30')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test30'
            })
            vm.init({ 'name' : 'test30' }).then(function(){
                assert.equal('test30', vm.config.config.vm[0].name)
                vm.init({ 'name' : 'test31' }).then(function() {
                    assert.equal('test31', vm.config.config.vm[1].name)
                    vm.init({ 'name' : 'test32' }).then(function() {
                        assert.equal('test32', vm.config.config.vm[2].name)
                        assert.equal(3, vm.config.config.vm.length)
                        rm('-rf', '/tmp/test30')
                        done()
                    }, done)
                }, done)
            }, done)
        })
        it('should throw error new virtual machine has an already used name', function(done){
            rm('-rf', '/tmp/test40')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test40'
            })
            vm.init({ 'name' : 'test40' }).then(function(){
                assert.equal('test40', vm.config.config.vm[0].name)
                vm.init({ 'name' : 'test40' }).then(function() {
                    assert.fail('Failed adding second \'test40\' machine.')
                }, function(err) {
                    assert.throws(function(){ throw err; }, Error)
                    assert.throws(function(){
                        throw err;
                    }, /For name 'test40' Virtual Machine\(s\)\/Group\(s\) name exists already. Please name the machine differently./)
                    rm('-rf', '/tmp/test40')
                    done()
                })
            }, done)
        })
    })
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////









    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    describe('#groupInit()', function(){
        it('should init a virtual group from #constructor() options ', function(done){
            rm('-rf', '/tmp/test100')
            var vm = new VirtualManager({
                'config': { 'group' : 'test100' },
                'logger': logger,
                'p': '/tmp/test100'
            })
            vm.groupInit().then(function(){
                assert.equal('test100', vm.config.config.vg[0].group)
                rm('-rf', '/tmp/test100')
                done()
            }, done)
        })
        it('should init a virtual group from #groupInit() argument', function(done){
            rm('-rf', '/tmp/test110')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test110'
            })
            vm.groupInit({ 'group' : 'test110' }).then(function(){
                assert.equal('test110', vm.config.config.vg[0].group)
                rm('-rf', '/tmp/test110')
                done()
            }, done)
        })
        it('should init multiple virtual groups from #groupInit() argument', function(done){
            rm('-rf', '/tmp/test120')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test120'
            })
            vm.groupInit({ 'group' : 'test120' }).then(function(){
                assert.equal('test120', vm.config.config.vg[0].group)
                vm.groupInit({ 'group' : 'test121' }).then(function() {
                    assert.equal('test121', vm.config.config.vg[1].group)
                    vm.groupInit({ 'group' : 'test122' }).then(function() {
                        assert.equal('test122', vm.config.config.vg[2].group)
                        assert.equal(3, vm.config.config.vg.length)
                        rm('-rf', '/tmp/test120')
                        done()
                    }, done)
                }, done)
            }, done)
        })
        it('should throw error new virtual group has an already used name', function(done){
            rm('-rf', '/tmp/test130')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test130'
            })
            vm.groupInit({ 'group' : 'test130' }).then(function(){
                assert.equal('test130', vm.config.config.vg[0].group)
                vm.groupInit({ 'group' : 'test130' }).then(function() {
                    assert.fail('Failed adding second \'test130\' machine.')
                }, function(err) {
                    assert.throws(function(){ throw err; }, Error)
                    assert.throws(function(){
                        throw err;
                    }, /For name 'test130' Virtual Group\(s\)\/Machine\(s\) name exists already. Please name the machine group differently./)
                    rm('-rf', '/tmp/test130')
                    done()
                })
            }, done)
        })

        it('should throw error new virtual machine has an already used name', function(done){
            rm('-rf', '/tmp/test140')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test140'
            })
            vm.groupInit({ 'group' : 'test140' }).then(function(){
                assert.equal('test140', vm.config.config.vg[0].group)
                vm.init({ 'name' : 'test140' }).then(function() {
                    assert.fail('Failed adding second \'test140\' machine.')
                }, function(err) {
                    assert.throws(function(){ throw err; }, Error)
                    assert.throws(function(){
                        throw err;
                    }, /For name 'test140' Virtual Machine\(s\)\/Group\(s\) name exists already. Please name the machine differently./)
                    rm('-rf', '/tmp/test140')
                    done()
                })
            }, done)
        })

        it('should throw error new virtual group has an already used name', function(done){
            rm('-rf', '/tmp/test150')
            var vm = new VirtualManager({
                'logger': logger,
                'p': '/tmp/test150'
            })
            vm.init({ 'name' : 'test150' }).then(function(){
                assert.equal('test150', vm.config.config.vm[0].name)
                vm.groupInit({ 'group' : 'test150' }).then(function() {
                    assert.fail('Failed adding second \'name\' group.')
                }, function(err) {
                    assert.throws(function(){ throw err; }, Error)
                    assert.throws(function(){
                        throw err;
                    }, /For name 'test150' Virtual Group\(s\)\/Machine\(s\) name exists already. Please name the machine group differently./)
                    rm('-rf', '/tmp/test150')
                    done()
                })
            }, done)
        })
    })
})