 /**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/
var hooker = require('../../src/hooker'),
    shell  = require('shelljs'),
    path   = require('path'),
    fs     = require('fs'),
    os     = require('os'),
    tempDir= path.join(__dirname, '..', '..', 'temp'),
    hooks  = path.join(__dirname, '..', 'fixtures', 'hooks'),
    cordova= require('../../cordova');

var platform = os.platform();
var cwd = process.cwd();

describe('hooker', function() {
    it('should throw if provided directory is not a cordova project', function() {
        shell.rm('-rf', tempDir);
        shell.mkdir('-p', tempDir); 
        this.after(function() {
            shell.rm('-rf', tempDir);
        });

        expect(function() {
            var h = new hooker(tempDir);
        }).toThrow();
    });
    it('should not throw if provided directory is a cordova project', function() {
        cordova.create(tempDir);
        this.after(function() {
            shell.rm('-rf', tempDir);
        });

        expect(function() {
            var h = new hooker(tempDir);
        }).not.toThrow();
    });

    describe('fire method', function() {
        var h;

        beforeEach(function() {
            cordova.create(tempDir);
            h = new hooker(tempDir);
        });
        afterEach(function() {
            shell.rm('-rf', tempDir);
        });

        describe('failure', function() {
            it('should not error if the hook is unrecognized', function(done) {
                h.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!', function(err){
                    expect(err).not.toBeDefined();
                    done();
                });
            });
            it('should error if any script exits with non-zero code', function(done) {
                var script;
                if (platform.match(/(win32|win64)/)) {
                    script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.bat');
                    shell.cp(path.join(hooks, 'fail', 'fail.bat'), script);
                } else {
                    script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.sh');
                    shell.cp(path.join(hooks, 'fail', 'fail.sh'), script);
                }
                fs.chmodSync(script, '754');
                h.fire('before_build', function(err){
                    expect(err).toBeDefined();
                    done();
                });
            });
        });

        describe('success', function() {
            it('should execute all scripts in order and fire callback', function(done) {
                var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
                if (platform.match(/(win32|win64)/)) {
                    shell.cp(path.join(hooks, 'test', '0.bat'), hook);
                    shell.cp(path.join(hooks, 'test', '1.bat'), hook);
                } else {
                    shell.cp(path.join(hooks, 'test', '0.sh'), hook);
                    shell.cp(path.join(hooks, 'test', '1.sh'), hook);
                }
                fs.readdirSync(hook).forEach(function(script) {
                    fs.chmodSync(path.join(hook, script), '754');
                });
                var returnValue;
                var s = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
                    cb(0, '');
                });
                h.fire('before_build', function(err) {
                    expect(err).not.toBeDefined();
                    if (platform.match(/(win32|win64)/)) {
                        expect(s.calls[0].args[0]).toMatch(/0.bat/);
                        expect(s.calls[1].args[0]).toMatch(/1.bat/);
                    } else {
                        expect(s.calls[0].args[0]).toMatch(/0.sh/);
                        expect(s.calls[1].args[0]).toMatch(/1.sh/);
                    }
                    done();
                });
            });
            it('should pass the project root folder as parameter into the project-level hooks', function(done) {
                var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
                if (platform.match(/(win32|win64)/)) {
                    shell.cp(path.join(hooks, 'test', '0.bat'), hook);
                } else {
                    shell.cp(path.join(hooks, 'test', '0.sh'), hook);
                }
                fs.readdirSync(hook).forEach(function(script) {
                    fs.chmodSync(path.join(hook, script), '754');
                });
                var s = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
                    cb(0, '');
                });
                h.fire('before_build', function(err) {
                    expect(err).not.toBeDefined();
                    var param_str;
                    if (platform.match(/(win32|win64)/)) {
                        param_str = '0.bat "'+tempDir+'"';
                    } else { 
                        param_str = '0.sh "'+tempDir+'"'; 
                    }
                    expect(s.calls[0].args[0].indexOf(param_str)).not.toEqual(-1);
                    done();
                });
            });
            describe('module-level hooks', function() {
                var handler = jasmine.createSpy();
                var test_event = 'before_build';
                afterEach(function() {
                    cordova.off(test_event, handler);
                    handler.reset();
                });

                it('should fire handlers using cordova.on', function(done) {
                    cordova.on(test_event, handler);
                    h.fire(test_event, function(err) {
                        expect(handler).toHaveBeenCalled();
                        expect(err).not.toBeDefined();
                        done();
                    });
                });
                it('should pass the project root folder as parameter into the module-level handlers', function(done) {
                    cordova.on(test_event, handler);
                    h.fire(test_event, function(err) {
                        expect(handler).toHaveBeenCalledWith({root:tempDir});
                        expect(err).not.toBeDefined();
                        done();
                    });
                });
                it('should be able to stop listening to events using cordova.off', function(done) {
                    cordova.on(test_event, handler);
                    cordova.off(test_event, handler);
                    h.fire(test_event, function(err) {
                        expect(handler).not.toHaveBeenCalled();
                        done();
                    });
                });
                it('should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
                    var h1_fired = false;
                    var h1 = function(root, cb) {
                        h1_fired = true;
                        setTimeout(cb, 100);
                    };
                    var h2_fired = false;
                    var h2 = function() {
                        h2_fired = true;
                    };
                    runs(function() {
                        cordova.on(test_event, h1);
                        cordova.on(test_event, h2);
                        h.fire(test_event, function(err) {
                            done();
                        });
                        expect(h1_fired).toBe(true);
                        expect(h2_fired).toBe(false);
                    });
                    waits(100);
                    runs(function() {
                        expect(h2_fired).toBe(true);
                    });
                });
            });
        });
    });
});
