/*
 * Copyright 2015-2016 IBM Corporation
 *
 * Licensed 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.
 */

'use strict'

const test = require('ava').test;
const uuid = require('uuid');
const spawn = require('child_process').spawn;
const Namer = require('../../lib/namer');
const colors = require('colors');

function Driver() {
}

function doTest(expectFailure, shouldDoThisSuccessfully, stepFn, args, rootPath) {
    return test(shouldDoThisSuccessfully, t => {
	return new Promise((resolve,reject) => {
	    const child = spawn('node', ['wskdb.js'].concat(args || []), { cwd: rootPath || '../..' });

	    const name = Namer.name('test');
	    const steps = stepFn(name);
	    
	    var stepNumber = 0;
	    var goody = false;

	    // for the dead man's switch
	    var lastStep;
	    var lastOut;

	    function doStep() {
		// console.log(("STEP " + steps[stepNumber]).green);
		lastStep = Date.now();
		child.stdin.write(steps[stepNumber++] + '\n');
	    }
	    function redoStep() {
		// console.log(("REDO STEP " + steps[stepNumber]).red);
		child.stdin.write(steps[stepNumber - 1] + '\n');
	    }
	    doStep(); // do the first step

	    setInterval(function deadMansSwitch() {
		if (lastStep > lastOut || (lastOut - lastStep < 100 && Date.now() - lastStep > 2000)) {
		    redoStep();
		}
	    }, 2000);

	    function errorInOutput() {
		goody = false;
		if (expectFailure) {
		    resolve();
		    return true;
		} else {
		    reject('Step ' + (stepNumber - 1) + ' failed');
		    return false;
		}
	    }
	    
	    child.stderr.on('data', (data) => {
		if (data.toString().indexOf('Error') >= 0) {
		    if (errorInOutput()) {
			//
			// don't print the error, as this was expected
			//
			return;
		    }
		}
		console.error(('stderr: ' + data).red);
	    });

	    child.stdout.on('data', (data) => {
		// console.log('stdout: '.blue + data);
		lastOut = Date.now(); // for the dead man's switch
		
		if (data.indexOf('Error') >= 0) {
		    errorInOutput();
			
		} else if (data.indexOf('ok') == 0
			   || data.indexOf('\nok\n') >= 0
			   || data.indexOf('break in') >= 0
			   || data.indexOf('stopped') >= 0) {
		    goody = true;
			
		    if (stepNumber === steps.length) {
			child.stdin.write('quit\n');
			child.stdin.end();
		    } else {
			doStep();
		    }
		}
	    });
	    child.on('exit', (code) => {
		if (code === 0 && goody) {
		    if (expectFailure) {
			reject('zero exit code');
		    } else {
			resolve();
		    }
		} else {
		    if (expectFailure) {
			resolve();
		    } else {
			reject();
		    }
		}
	    });
	}).then(result => t.is(result));
    });
} /* the end of it! */

function should(shouldDoThisSuccessfully, stepFn, args, rootPath) {
    return doTest(false, shouldDoThisSuccessfully, stepFn, args, rootPath);
};
function shouldFail(shouldDoThisSuccessfully, stepFn, args, rootPath) {
    return doTest(true, shouldDoThisSuccessfully, stepFn, args, rootPath);
};

Driver.prototype.it = {
    should: should,
    shouldFail: shouldFail
};

module.exports = new Driver().it;
