var assert = require('assert')
  , mock = require('mock-fs')
  , fs = require('fs')
  , gh = require('../lib/git-hooked')
  , hooks = require('../lib/hooks')
  , utils = require('../lib/utils');

describe('Git-Hooked Setup', function() {

  afterEach('restore fs', mock.restore);

  it('checks for git project', function() {
    mock({
      '.git': {
        'hooks': {}
      }
    });
    assert.equal(true, gh.isGitProject());
  });

  it('checks for user hooks directory', function() {
    mock({
      '.hooks': {}
    });
    assert.equal(true, gh.hasUserHooksDir());
  });

  it('installs all hooks', function() {
    mock({
      '.hooks': hooks.reduce(function(o, v) { o[v] = ''; return o; }, {}),
      '.git/hooks': {},
      'lib': {
        'hook.template.js': ''
      }
    });
    gh.installHooks();
    hooks.forEach(function(hook) {
      assert.equal(true, utils.fileExists('.git/hooks/' + hook));
    });
    assert.equal(hooks.length, fs.readdirSync('.git/hooks').length);
  });

  it('installs only single hook', function() {
    mock({
      '.hooks': hooks.reduce(function(o, v) { o[v] = ''; return o; }, {}),
      '.git/hooks': {},
      'lib': {
        'hook.template.js': ''
      }
    });
    gh.installHooks('pre-commit');
    assert.equal(true, utils.fileExists('.git/hooks/pre-commit'));
    assert.equal(1, fs.readdirSync('.git/hooks').length);
  });

  it('installs only user defined hooks', function() {
    mock({
      '.hooks': {
        'pre-commit': '',
        'post-commit': ''
      },
      '.git/hooks': {},
      'lib': {
        'hook.template.js': ''
      }
    });
    gh.installHooks();
    assert.equal(true, utils.fileExists('.git/hooks/pre-commit'));
    assert.equal(true, utils.fileExists('.git/hooks/post-commit'));
    assert.equal(false, utils.fileExists('.git/hooks/pre-receive'));
  });

  it('backups existing user hooks', function() {
    mock({
      '.hooks': {
        'pre-commit': ''
      },
      '.git/hooks': {
        'pre-commit': ''
      }
    });
    gh.installHooks();
    assert.equal(true, utils.fileExists('.git/hooks/pre-commit'));
    assert.equal(true, utils.fileExists('.git/hooks/pre-commit.user'));
  });

  it('replaces existing git-hooked hook', function() {
    mock({
      '.hooks': {
        'post-commit': ''
      },
      '.git/hooks': {
        'post-commit': '/*! Generated by git-hooked. Do not modify! */'
      }
    });
    gh.installHooks();
    assert.equal(true, utils.fileExists('.git/hooks/post-commit'));
    assert.equal(false, utils.fileExists('.git/hooks/post-commit.user'));
  });

  it('creates executable hook runner', function() {
    mock({
      '.hooks': {
        'pre-commit': ''
      },
      '.git/hooks': {}
    })
    gh.installHooks();
    assert.equal('755', (fs.statSync('.git/hooks/pre-commit').mode & 07777).toString(8));
  });

});