var fs = require('fs');
var path = require('path');

var chai = require('chai');
var stripAnsi = require('strip-ansi');
var expect = chai.expect;
var mockPackageJson = JSON.parse(fs.readFileSync(path.join(__dirname, './mocks/mockPackageConfig.json'), 'utf8'));
var moduleUtils = require('../index.js');
var moduleUtilsInstance = moduleUtils(mockPackageJson);

var mockConsoleLog = require('./mocks/mockConsoleLog');
var mockProcessExit = require('./mocks/mockProcessExit');

chai.use(require('chai-fs'));
chai.should();

describe('As user of the module utils module', function() {

	it('should export a function', function() {
		expect(moduleUtils).to.be.an('function');
	})

	describe('When creating an instance', function() {

		it('should return an object', function() {
			expect(moduleUtilsInstance).to.be.an('object');
		})
	})

	describe('When using the logMessage function', function() {

		before(function() {
			mockConsoleLog.enable();
		})

		after(function() {
			// mockConsoleLog.removeLogFile();
			mockConsoleLog.clearLogData();
		})

		it('should correctly log the input', function() {
			var logInput = "Who are the patriots?"
			var expected = fs.readFileSync(path.join(__dirname, 'structs', 'logMessage.txt'), 'utf8');
			var actual;

			moduleUtilsInstance.logMessage(logInput);
			mockConsoleLog.restore();

			// actual = mockConsoleLog.getFileContents();
			actual = mockConsoleLog.getLogData();

			expect(expected).to.equal(actual);
		});

	})

	describe('When using the finishInstall function', function() {

		describe('And testing the on-screen output', function() {

			before(function() {
				mockConsoleLog.enable();

				mockProcessExit.enable();
			})

			after(function() {
				// mockConsoleLog.removeLogFile();
				mockConsoleLog.clearLogData();
			})

			it('should correctly log the input', function() {
				var expected = fs.readFileSync(path.join(__dirname, 'structs', 'finishInstall.txt'), 'utf8');
				var actual;

				moduleUtilsInstance.finishInstall();
				mockConsoleLog.restore();
				mockProcessExit.restore();
				// actual = mockConsoleLog.getFileContents();
				actual = mockConsoleLog.getLogData();

				expect(expected).to.equal(actual);
			})
		})

		describe('And testing if the process it exited', function() {

			before(function() {
				mockProcessExit.enable();
				mockConsoleLog.enable();
			})

			after(function() {
				mockProcessExit.restore();
			})

			it('should exit the process with error code 0 (no error)', function() {
				var exitCallInfo;

				moduleUtilsInstance.finishInstall();
				mockConsoleLog.restore();

				exitCallInfo = mockProcessExit.callInfo();

				expect(exitCallInfo.called).to.be.true;
				expect(exitCallInfo.errorCode).to.equal(0);
			})

		})

	})

	describe('When using the exitIfDevEnvironment', function() {

		describe('And NODE_ENV equals `development`', function() {

			beforeEach(function() {
				mockProcessExit.enable();
				mockConsoleLog.enable({
					writeToFile: true
				});

				process.env.NODE_ENV = 'development';
			})

			afterEach(function() {
				mockProcessExit.restore();
				mockConsoleLog.removeLogFile();
			})

			it('should output on-screen message saying this step is going to be skipped', function() {
				var expected = fs.readFileSync(path.join(__dirname, 'structs', 'exitIfDev.txt'), 'utf8');
				var actual;

				moduleUtilsInstance.exitIfDevEnvironment();
				mockConsoleLog.restore();
				//@TODO change mockConsoleLog.getFileContents(); to allow to be used asynchronously
				actual = stripAnsi(fs.readFileSync(path.join(__dirname, 'console.log'), 'utf8'));

				expect(expected).to.equal(actual);

			})

			it('should exit the process with error code 0 (no error)', function() {
				var exitCallInfo;

				moduleUtilsInstance.exitIfDevEnvironment();
				mockConsoleLog.restore();

				exitCallInfo = mockProcessExit.callInfo();

				expect(exitCallInfo.called).to.be.true;
				expect(exitCallInfo.errorCode).to.equal(0);
			})

		})

		describe('And NODE_ENV does not equal `development`', function() {
			beforeEach(function() {
				mockProcessExit.enable();
				// mockConsoleLog.enable({
				// 	writeToFile: true
				// });

				process.env.NODE_ENV = 'played-me-like-a-damn-fiddle';
			})

			afterEach(function() {
				mockProcessExit.restore();
				// mockConsoleLog.removeLogFile();
			})

			it.skip('should not output an on-screen message', function() {
				//@TODO
			});

			it('should not exit the process', function() {
				var exitCallInfo;

				moduleUtilsInstance.exitIfDevEnvironment();
				exitCallInfo = mockProcessExit.callInfo();

				expect(exitCallInfo.called).to.be.false;
			})
		})

	})
})
@@ -971,46 +971,8 @@
 ) %7B%0A
-%09%09%09// mockConsoleLog.removeLogFile();%0A
 %09%09%09m
@@ -997,24 +997,24 @@
 rLogData();%0A
+
 %09%09%7D)%0A%0A%09%09it('
@@ -1290,57 +1290,8 @@
 );%0A%0A
-%09%09%09// actual = mockConsoleLog.getFileContents();%0A
 %09%09%09a
@@ -1620,47 +1620,8 @@
 ) %7B%0A
-%09%09%09%09// mockConsoleLog.removeLogFile();%0A
 %09%09%09%09
@@ -1889,32 +1889,32 @@
 eLog.restore();%0A
+
 %09%09%09%09mockProcessE
@@ -1932,58 +1932,8 @@
 ();%0A
-%09%09%09%09// actual = mockConsoleLog.getFileContents();%0A
 %09%09%09%09
@@ -3919,76 +3919,8 @@
 e();
-%0A%09%09%09%09// mockConsoleLog.enable(%7B%0A%09%09%09%09// %09writeToFile: true%0A%09%09%09%09// %7D);
 %0A%0A%09%09
@@ -4044,47 +4044,8 @@
 ();%0A
-%09%09%09%09// mockConsoleLog.removeLogFile();%0A
 %09%09%09%7D

remove coments