# Source: Reporter.js

    /**
     * Created by 212556710 on 4/28/16.
     */
    module.exports = function JsonOutputHook() {
        var Cucumber = require('cucumber');
        var logger = require('./Logger.js');
        var Promise = require('bluebird');
        //var RallyHelper = require('./RallyHelper.js');
        var JsonFormatter = Cucumber.Listener.JsonFormatter();
        var json_rally = '';
        var cucumber_json = '';
        var fs = require('fs');
        var dir = './Reports/json_report';
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir);
        }
        var special_char_tf = false;//add special char check
        var special_char_tc = false;
        var special_char_step = false;
        var wroteFile = false;
        var eof = false;
        var imageCount = 0;
        this.registerListener(JsonFormatter);
        JsonFormatter.log = function (jsonold, callback) {

            // Loops through the provided array to check if the test case has arguements
            var checkarray = function (array, str_to_check) {
                var num_times = 0;
                for (var temp = 0; temp < array.length; temp++) {
                    if (array[temp] == str_to_check) {
                        num_times++;
                        has_arg = true;
                    }
                    if (temp == array.length - 1)
                        return (num_times);
                }
            }

            var RallyJson = JSON.parse(jsonold);
            var has_arg = false;
            var duplicate_arg = false;

            // For loop to go through all the feature files
            for (var feature = 0; feature < RallyJson.length; feature++) {

                var feature_name = RallyJson[feature].name;
                var args = [];
                // var re = /\(|\)/;
                // var TFchars = re.test(feature_name);

                // if (TFchars) {
                //     special_char_tf = true;
                //     console.log('Error in Feature Name');
                //     logger.info('Error in Feature Name');
                //     break;
                // }
                // else {
                //     special_char_tf = false;
                // }
                for (var scenario = 0; scenario < RallyJson[feature].elements.length; scenario++) {
                    var scenario_name = RallyJson[feature].elements[scenario].name;
                    // var TCspecial_chars = /\(|\)/;
                    // var check_chars = TCspecial_chars.test(scenario_name);
                    // if (check_chars) {
                    //     special_char_tc = true;
                    //     console.log('Error in Scenario Name');
                    //     logger.info('Error in Scenario Name');
                    //     break;
                    // } else {
                    //     special_char_tc = false;
                    // }

                    // This variable is going to hold the array of user stories
                    var arrUserStory = "";
                    var testCaseNumber = "";
                    var testcaseName = "";

                    //read user story from env file
                    if (process.env.user_story != undefined && process.env.user_story != "") {
                        arrUserStory = process.env.user_story;
                        arrUserStory = arrUserStory.match(/US[0-9]+/g);
                    }

                    //read user story from feature file
                    var checkUserStory = scenario_name.split(":");
                    if (process.env.overwrite_US == "false" || process.env.overwrite_US == undefined) {

                        if (checkUserStory.length == 2) {
                            if (checkUserStory[0].match(/US[0-9]+/g)) {
                                arrUserStory = checkUserStory[0];
                                arrUserStory = arrUserStory.match(/US[0-9]+/g);
                            }
                            else {
                                testCaseNumber = checkUserStory[0];
                            }
                            testcaseName = checkUserStory[1]
                        }
                        // Checking to see if TC number is defined here. Then grabs the right index for the split array to get the user story
                        else if (checkUserStory.length == 3) {
                            if (checkUserStory[0].match(/US[0-9]+/)) {
                                arrUserStory = checkUserStory[0];
                                testCaseNumber = checkUserStory[1]
                            }
                            else {
                                testCaseNumber = checkUserStory[0]
                                arrUserStory = checkUserStory[1];
                            }
                            arrUserStory = arrUserStory.match(/US[0-9]+/g);
                            testcaseName = checkUserStory[2]
                        }
                        else {
                            testcaseName = checkUserStory[0]
                        }
                    }

                    // If env overwrite US is set to true but we still need to get the test case number if there is one
                    else {
                        if (checkUserStory.length == 2) {
                            if (!checkUserStory[0].match(/US[0-9]+/g)) {
                                testCaseNumber = checkUserStory[0];
                            }
                            testcaseName = checkUserStory[1]
                        }
                        // Checking to see if TC number is defined here. Then grabs the right index for the split array to get the user story
                        else if (checkUserStory.length == 3) {
                            if (checkUserStory[0].match(/US[0-9]+/)) {
                                testCaseNumber = checkUserStory[1]
                            }
                            else {
                                testCaseNumber = checkUserStory[0]
                            }
                            testcaseName = checkUserStory[2]
                        }
                        else {
                            testcaseName = checkUserStory[0]
                        }
                    }

                    // This is to replace the scenario name with the correct userstory whether it got it from the env or feature file

                    if (arrUserStory != "")
                        var userStoryString = arrUserStory.join(",");

                    if (testCaseNumber != "") {
                        if (userStoryString == undefined && testCaseNumber != undefined) {
                            userStoryString = testCaseNumber;
                        }
                        else {
                            userStoryString += ":" + testCaseNumber;
                        }
                    }

                    if (checkUserStory.length > 1 && (process.env.overwrite_US == "false" || process.env.overwrite_US == undefined)) {
                        RallyJson[feature].elements[scenario].name = userStoryString + ":" + testcaseName;;
                    } else if (userStoryString != "" && userStoryString!=undefined) {
                        RallyJson[feature].elements[scenario].name = userStoryString+":"+testcaseName;
                    }
                    else {
                        RallyJson[feature].elements[scenario].name = checkUserStory[0];
                    }
                    //if there are multiple user story.
                    if (arrUserStory != null && arrUserStory.length > 1) {
                        var name = RallyJson[feature].elements[scenario].name;
                        RallyJson[feature].elements[scenario].name = checkUserStory[0].replace(/(,(\s*)?US[0-9]+)+/g, "") + ":" + checkUserStory[1] + "_US_1";
                        scenario_name = RallyJson[feature].elements[scenario].name;
                        for (var i = 1; i < arrUserStory.length; i++) {
                            var temp_element = JSON.parse(JSON.stringify(RallyJson[feature].elements[scenario]));
                            var temp_element_userstory = temp_element.name.split(":")[0].replace(/US[0-9]+/g, arrUserStory[i])
                            temp_element.name = temp_element_userstory + ":" + temp_element.name.split(":")[1].substring(0, temp_element.name.split(":")[1].length - 2) + "_" + (i + 1);
                            RallyJson[feature].elements.push(temp_element);
                        }
                    }

                    for (var step = 0; step < RallyJson[feature].elements[scenario].steps.length; step++) {
                        if (RallyJson[feature].elements[scenario].steps[step].name != undefined) {
                            var name = RallyJson[feature].elements[scenario].steps[step].name;
                            // var stepSPChar = /\(|\)/;
                            // var check_StepChars = stepSPChar.test(name);
                            // if (check_StepChars) {
                            //     special_char_step = true;
                            //     console.log('Error in step declaration');
                            //     logger.info('Error in step declaration');
                            //     break;
                            // } else {
                            //     special_char_step = false;
                            // }
                            var reg_exp = new RegExp('\".+?\"');
                            var arg = reg_exp.exec(name);
                            if (arg != undefined) {
                                has_arg = true;
                                if (args.length > 0) {
                                    var retrned = checkarray(args, arg[0]);
                                    if (retrned > 0) {
                                        duplicate_arg = true;
                                        RallyJson[feature].elements[scenario].name = scenario_name + ' ' + arg[0] + ' ' + retrned;
                                        RallyJson[feature].elements[scenario].name = RallyJson[feature].elements[scenario].name.split('"').join('');

                                    } else {
                                        RallyJson[feature].elements[scenario].name = scenario_name + ' ' + arg[0];
                                        RallyJson[feature].elements[scenario].name = RallyJson[feature].elements[scenario].name.split('"').join('');

                                    }
                                }
                                args.push(arg[0]);
                            } else if (step == RallyJson[feature].elements[scenario].steps.length - 2) {
                                has_arg = false;
                                break;
                            }
                        } else if (step == RallyJson[feature].elements[scenario].steps.length - 2) {
                            has_arg = false;
                            break;
                        }
                    }
                    if (special_char_step)
                        break;
                    if ((scenario == RallyJson[feature].elements.length - 1) && (feature == RallyJson.length - 1)) {
                        json_rally = JSON.stringify(RallyJson, null, "\t");
                        cucumber_json = jsonold;
                    }
                }
                if (special_char_tc || special_char_step || wroteFile) {
                    break;
                }
            }
        };

        this.After(function (scenario, callback) {
            console.log('after scenario');
            if (scenario.isFailed()) {
                Logger.info("Results: Failed");
                browser.takeScreenshot().then(function (png) {
                    imageCount += 1;
                    var decodedImage = new Buffer(png, "base64").toString("binary");
                    fs.writeFile("Reports/image" + imageCount + ".png", decodedImage, 'binary', function (err) {
                        scenario.attach(decodedImage, "image/png");
                        console.log("Attached");
                        callback()
                    })
                });
            } else {
                Logger.info("Results: Passed");
                callback();
            }
        });

        this.registerHandler('BeforeScenario', function (event, callback) {
            var scenario = event.getPayloadItem('scenario');
            Logger.info("|--------------------------------------------------------|");
            Logger.info("Test " + scenario.getName() + " has started");
            Logger.info("|--------------------------------------------------------|\r\n");
            callback();
        });

        this.registerHandler('AfterScenario', function (event, callback) {
            var scenario = event.getPayloadItem('scenario');
            Logger.info("|--------------------------------------------------------|");
            Logger.info("Test " + scenario.getName() + " has ended");
            Logger.info("|--------------------------------------------------------|\r\n\r\n");
            callback();
        });

        this.registerHandler('AfterFeatures', function (features, callback) {
            if (json_rally == '') {
                //spin for loop until json rally finished
                var date = new Date();
                while (new Date() - date < 1500) {
                    //spin for 1.5 sec
                }
            }
            fs.writeFile('Reports/json_report/rally.json', json_rally, function (err) {
                if (err) console.log(err);
                else {
                    //fs.writeFile('Reports/json_report/cucumber.json', cucumber_json, function (err) {
                    //     if (err) console.log(err);
                    var Rally = require('./Rally.js');
                    if ((!special_char_tf) && (!special_char_tc) && (!special_char_step)) {
                        Rally.RallyWebAPI('../../../Reports/json_report/rally.json', function () {
                            wroteFile = true;
                            callback();
                        });
                    } else {
                        console.log('The following characters are not supported in postToRally:' +
                            ' "(" and ")" - please check your feature file');
                        logger.info('The following characters are not supported in postToRally:' +
                            ' "(" and ")" - please check your feature file');
                        callback();
                    }
                    //});
                }
            });
        });
    };