# Source: RallyHelper.js

    /**
     * Created by 212571071 on 7/21/16.
     */
    /**
     * Copyright (c) 2013 - 2014 GE Global Research. All rights reserved.
     * The copyright to the computer software herein is the property of
     * GE Global Research. The software may be used and/or copied only
     * with the written permission of GE Global Research or in accordance
     * with the terms and conditions stipulated in the agreement/contract
     * under which the software has been supplied.
     */

    (function () {

        var logger = require('./Logger.js');
        var request = require('request-promise');
        require('dotenv').config();
        var build_num,testset,postOnlyTS;
        if (process.env.build_no != undefined)
            build_num = process.env.build_no;
        else build_num = 1;

        for (var arg = 0; arg < process.argv.length; arg++) {
            var temp1 = process.argv[arg].split('=');
            if (temp1[0] == "--params") {
                var param = process.argv[arg];
                var args = param.split('=');
                var indiv = args[1].split(',');
                var apikey = indiv[0];
                apikey = apikey.split(':'); // apikey is: apikey[1]
            }
        }
        var User_Story;
        if (process.env.rallyworkspace != undefined)
            var workspace = process.env.rallyworkspace;
        else
            workspace = "";   // default workspace
        if (process.env.method != undefined)
            var method = process.env.method;
        else
            var method = "Automated";   // default workspace
        if (process.env.rallyProxy != undefined) {
            var proxy = process.env.rallyProxy;
        } else {
            logger.info('No proxy defined - check .env file');
            console.log('No proxy defined - check .env file');
            callback();
        }
        var zsessionid;
        if (apikey != undefined)
            zsessionid = apikey[1];
        else if ((apikey == undefined) && (process.env.apiKey != undefined))
            zsessionid = process.env.apiKey;
        else {
            logger.info('No apiKey provided - check .env file or command line parameter');
            console.log('No apiKey provided - check .env file or command line parameter');
            callback();
        }
        var baseUrl = 'https://rally1.rallydev.com/slm/webservice/v2.0/';
        /**
         * Creates new RestHelper
         * @class RestHelper
         */
        var RallyHelper = function () {

            return {
                queryUserStory: function (user_story, json, i, j, test_case_name, test_case_description, glb_folder_id, line, duration, status, callbck) {
                    var user_story_id;
                    var request = require("request-promise");
                    var options = {
                        method: 'GET',
                        url: 'https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement?' +
                        'query=(FormattedID%20%3D%20' + user_story + ')&fetch=true',
                        headers: {zsessionid: zsessionid},
                        proxy: proxy
                    };
                    var to_return;
                    request(options)
                        .then(function (body,error) {
                            if (error) {
                                console.log('error: ' + error);
                                callbck(to_return);
                            } else {
                                //console.log('body US: ' + body);
                                var json_body = JSON.parse(body);
                                if (json_body.QueryResult.TotalResultCount > 0) {
                                    user_story_id = json_body.QueryResult.Results[0].ObjectID;
                                } else {
                                    user_story_id = '';
                                }
                                to_return = {
                                    body: json_body,
                                    user_story_id: user_story_id,
                                    json: json,
                                    i: i,
                                    j: j,
                                    test_case_name: test_case_name,
                                    test_case_description: test_case_description,
                                    glb_folder_id: glb_folder_id,
                                    line: line,
                                    duration: duration,
                                    status: status
                                }
                                return callbck(to_return);
                            }
                        });
                },
                queryTestCases: function (test_case, json, i, j, user_story, glb_folder_id, callbck){
                    var last_run = false; var test_case_result_id = 0;
                    var request = require("request-promise");
                    var options = {
                        method: 'GET',
                        url: baseUrl + 'testcase?query=(Name%20%3D%20' + test_case + ')&fetch=true',
                        headers: {
                            zsessionid: zsessionid
                        },
                        proxy: proxy
                    };
                    var revision_history_ref;
                    request(options)
                        .then(function (body,error) {
                            var id = 0;
                            if (error) {
                                console.log("Rally error: " + error);
                            } else {
                                // console.log('else case:');
                                // console.log('query test case: ' + body);
                                var json_body = JSON.parse(body);
                                //console.log('last result is: ' + JSON.stringify(json_body.QueryResult.Results[0].LastResult));
                                if (json_body.QueryResult.TotalResultCount > 0) {
                                    if (json_body.QueryResult.Results[0]._refObjectName == test_case) {

                                        if(json_body.QueryResult.Results[0].LastResult == null) {
                                            //console.log('no result');
                                            last_run = false;
                                        } else {
                                            last_run = true;
                                            test_case_result_id = json_body.QueryResult.Results[0].LastResult._ref;
                                            test_case_result_id = test_case_result_id.split('/');
                                            test_case_result_id = test_case_result_id[7];
                                            //console.log('test case result id: ' + test_case_result_id);
                                        }
                                        id = json_body.QueryResult.Results[0].ObjectID;
                                        //console.log('id in test case is: ' + id);
                                        if(json_body.QueryResult.Results[0].RevisionHistory._ref != null)
                                            revision_history_ref = json_body.QueryResult.Results[0].RevisionHistory._ref;
                                        else
                                            revision_history_ref = '';
                                        found = true;
                                    } else {
                                        found = false;
                                        last_run = false;
                                    }
                                } else {
                                    found = false;
                                    last_run = false;
                                }
                                var to_return = {
                                    found: found,
                                    json: json,
                                    i: i,
                                    j: j,
                                    id: id,
                                    case_name: test_case,
                                    user_story: user_story,
                                    glb_folder_id: glb_folder_id,
                                    last_run: last_run,
                                    test_case_result_id:test_case_result_id,
                                    revision_history_ref:revision_history_ref
                                };
                                callbck(to_return);
                            }
                        });
                },
                queryTestFolders: function (test_plan, json, i, j, folder_id, callbck) {
                    var request = require("request-promise");
                    var options = {
                        method: 'GET',
                        url: baseUrl + 'testfolder?query=(Name%20%3D%20' + test_plan + ')&fetch=true',
                        headers: {
                            zsessionid: zsessionid
                        },
                        proxy: proxy
                    };
                    request(options)
                        .then(function (body, error) {
                            var folderID = 0;
                            if (error) {
                                console.log("Rally error: " + error);
                            } else {
                                //console.log('query TF: ' + body);
                                var json_body = JSON.parse(body);
                                if (json_body.QueryResult.TotalResultCount > 0) {
                                    if (json_body.QueryResult.Results[0]._refObjectName == test_plan) {
                                        if ((folder_id == 0) || (json_body.QueryResult.Results[0].Parent != null)) {
                                            folderID = json_body.QueryResult.Results[0].ObjectID;
                                            found = true;
                                        } else {
                                            found = false
                                        }
                                    } else {
                                        found = false;
                                    }
                                } else {
                                    found = false;
                                }
                                var to_return = {
                                    found: found,
                                    json: json,
                                    i: i,
                                    j: j,
                                    folderID: folderID,
                                    test_plan: test_plan
                                };
                                callbck(to_return);
                            }
                        });

                },
                queryTestSet: function(testset, status, duration, glb_test_case_id, glb_folder_id, json, i, j, k, callbck) {
                    if(testset==''){
                        to_return = {
                            test_set_id:'',
                            status:status,
                            duration:duration,
                            glb_test_case_id:glb_test_case_id,
                            glb_folder_id:glb_folder_id,
                            json:json,
                            i:i,
                            j:j,
                            k:k
                        }
                        callbck(to_return);
                    } else {
                        var request = require('request-promise');
                        var test_set_id;
                        var options = {
                            method: 'GET',
                            url: 'https://rally1.rallydev.com/slm/webservice/v2.0/testset?' +
                            'query=(FormattedID%20%3D%20' + testset + ')&fetch=true',
                            headers: {zsessionid: zsessionid},
                            proxy: proxy
                        };
                        var to_return;
                        request(options)
                            .then(function (body, error) {
                                //console.log('query test set: ' + body);
                                var json_body = JSON.parse(body);
                                if (json_body.QueryResult.TotalResultCount > 0) {
                                    test_set_id = json_body.QueryResult.Results[0].ObjectID;
                                } else {
                                    test_set_id = '';
                                }
                                to_return = {
                                    test_set_id: test_set_id,
                                    status: status,
                                    duration: duration,
                                    glb_test_case_id: glb_test_case_id,
                                    glb_folder_id: glb_folder_id,
                                    json: json,
                                    i: i,
                                    j: j,
                                    k: k
                                }
                                callbck(to_return);
                            });
                    }
                },
                queryRevisionHistory: function(revision_history_ref, user_story, json, i, j, test_case_name, test_case_description, glb_folder_id, line, duration, status, callbck){
                    var request = require("request-promise");
                    var options = {
                        method: 'GET',
                        url: revision_history_ref + '/Revisions',
                        headers:
                        {  zsessionid:zsessionid},
                        proxy:proxy
                    };
                    var owner_url, owner;
                    request(options)
                        .then(function (body,error) {
                            if(error) {
                                console.log('Rally error: '+ error);
                                callbck();
                            }
                            else {
                                //console.log('revision history: ' + body);
                                var json_body = JSON.parse(body);
                                if(json_body.QueryResult.TotalResultCount > 0){
                                    owner_url = json_body.QueryResult.Results[0].User._ref;
                                    owner = owner_url.split('/');
                                    var to_return = {
                                        owner: owner[7],
                                        user_story: user_story,
                                        json:json,
                                        i:i,
                                        j:j,
                                        test_case_name: test_case_name,
                                        test_case_description:test_case_description,
                                        glb_folder_id: glb_folder_id,
                                        line:line,
                                        duration:duration,
                                        status:status
                                    }

                                    callbck(to_return);
                                }
                            }
                        });
                },
                createTestPlan: function (test_plan, test_plan_description, parent_folder, json, i, j, callbck) {
                    var body, folder_id;
                    if (parent_folder == 0) {
                        if (workspace != "") {
                            body = '{\n' +
                                '    "testfolder":\n' +
                                '         {\n' +
                                '              "Name":"' + test_plan + '",\n' +
                                '              "Workspace":"/Workspace/' + workspace + '"\n' +
                                '         }\n' +
                                '}'
                        } else {
                            body = '{\n' +
                                '    "testfolder":\n' +
                                '         {\n' +
                                '              "Name":"' + test_plan + '"\n' +
                                '         }\n' +
                                '}'
                        }
                    } else {
                        if (workspace != "") {
                            body = '{\n' +
                                '    "testfolder":\n' +
                                '        {\n' +
                                '            "Name":"' + test_plan + '" ,\n' +
                                '            "Parent":"' + parent_folder + '"\n' +
                                '            "Workspace":"/Workspace/' + workspace + '"\n' +
                                '        }\n' +
                                '}'
                        } else {
                            body = '{\n' +
                                '    "testfolder":\n' +
                                '        {\n' +
                                '            "Name":"' + test_plan + '" ,\n' +
                                '            "Parent":"' + parent_folder + '"\n' +
                                '        }\n' +
                                '}'
                        }
                    }
                    var to_return;
                    var request = require("request-promise");
                    var options = {
                        method: 'POST',
                        url: baseUrl + 'testfolder/create?fetch=true',
                        headers: {
                            zsessionid: zsessionid
                        },
                        body: body,
                        proxy: proxy
                    };
                    request(options)
                        .then(function (body,error) {
                            if (error) {
                                console.log("Rally error: " + error);
                            }
                            else {
                                //console.log('create test plan: ' + body);
                                var json_body = JSON.parse(body);
                                folder_id = json_body.CreateResult.Object.ObjectID;
                                to_return = {
                                    json: json,
                                    i: i,
                                    j: j,
                                    id: folder_id
                                }
                            }
                            return callbck(to_return);
                        });
                },
                createTestCaseResult: function (name, status, duration, test_case_id, glb_folder_id, json, i, j, k, testset, callbck) {
                    if (duration > 9999999999) {
                        duration = 9999999999;
                    }
                    if (status == 'passed') {
                        status = 'Pass';
                    } else if (status == "failed") {
                        status = 'Fail';
                    } else if (status == "skipped") {
                        status = 'Inconclusive';
                        duration = 0;
                    }

                    var d = new Date();
                    var date = d.toISOString();
                    var request = require("request-promise");
                    var options = {
                        method: 'POST',
                        url: baseUrl + 'testcaseresult/create',
                        headers: {
                            zsessionid: zsessionid
                        },
                        proxy: proxy,
                        body:
                        '{\n    "testcaseresult":\n' +
                        '        {\n' +
                        '            "TestCase":"/testcase/' + test_case_id + '",\n' +
                        '            "Build":"' + name + '",\n' +
                        '            "Duration":"' + duration + '",\n' +
                        '            "Verdict":"' + status + '",\n' +
                        '            "Date":"' + date + '",\n' +
                        '            "TestSet":"' + testset + '"\n' +
                        '        }\n' +
                        '}'
                    };
                    var id=0;
                    request(options)
                        .then(function (body,error) {
                            if (error) {
                                console.log("Rally error: " + error);
                            } else {
                                //console.log('result created: ' + body);
                                body = JSON.parse(body);
                                var err = body.CreateResult.Errors;
                                if(err != '') {
                                    //console.log('concurrency error: calling again should call again');
                                    id=null;
                                    //return callbck('concurrency');
                                }
                                else {
                                    id = body.CreateResult.Object.ObjectID;
                                }
                                var to_return = {
                                    json: json,
                                    i: i,
                                    j: j,
                                    k: k,
                                    id:id
                                };
                                return callbck(to_return);
                            }
                        });
                },
                createTestCase: function (test_case_name, test_case_description, folder_id, json, i, j, k, duration, line, status, user_story, callbck_create) {
                    //console.log('in create TC: ' + test_case_name);
                    var request = require('request-promise');
                    if (duration == undefined) {
                        duration = 0;
                    }
                    if (folder_id == null) {
                        folder_id = glb_subfolder_id;
                    }
                    var create_id = 0;
                    var to_ret, body;
                    if (test_case_description == "") {
                        test_case_description = "N/A";
                    }
                    if (workspace != "") {
                        if (User_Story != "") { // defined user story & workspace
                            body = '{\n' +
                                '    "testcase":\n' +
                                '        {\n' +
                                '            "Name":"' + test_case_name + '",\n' +
                                '            "Description":"' + test_case_description + '",\n' +
                                '            "Method":"'+method+'",\n' +
                                '            "TestFolder":"' + folder_id + '",\n' +
                                '            "Workspace":"/Workspace/' + workspace + '",\n' +
                                '            "WorkProduct":"' + user_story + '"\n' +
                                '        }\n' +
                                '}'
                        } else {            //no user story & defined workspace
                            body = '{\n' +
                                '    "testcase":\n' +
                                '        {\n' +
                                '            "Name":"' + test_case_name + '",\n' +
                                '            "Description":"' + test_case_description + '",\n' +
                                '            "Method":"'+method+'",\n' +
                                '            "TestFolder":"' + folder_id + '",\n' +
                                '             "Workspace":"/Workspace/' + workspace + '"\n' +
                                '        }\n' +
                                '}'
                        }
                    } else {
                        if (User_Story != "") {  //no defined workspace / defined user story
                            body = '{\n' +
                                '    "testcase":\n' +
                                '        {\n' +
                                '            "Name":"' + test_case_name + '",\n' +
                                '            "Description":"' + test_case_description + '",\n' +
                                '            "Method":"'+method+'",\n' +
                                '            "TestFolder":"' + folder_id + '",\n' +
                                '            "WorkProduct":"' + user_story + '"\n' +
                                '        }\n' +
                                '}'
                        } else {
                            body = '{\n' +
                                '    "testcase":\n' +
                                '        {\n' +
                                '            "Name":"' + test_case_name + '",\n' +
                                '            "Description":"' + test_case_description + '",\n' +
                                '            "Method":"'+method+'",\n' +
                                '            "TestFolder":"' + folder_id + '"\n' +
                                '        }\n' +
                                '}'
                        }
                    }
                    var options = {
                        method: 'POST',
                        url: baseUrl + 'testcase/create',
                        headers: {
                            zsessionid: zsessionid
                        },
                        proxy: proxy,
                        body: body
                    };
                    request(options)
                        .then( function (body,error) {
                            if (error) {
                                console.log('Rally error: ' + error);
                                to_ret = {
                                    json: json,
                                    i: i,
                                    j: j,
                                    k: k,
                                    duration: duration,
                                    line: line,
                                    id: 'returned null',
                                    status: status,
                                    folder_id: folder_id,
                                    user_story: user_story
                                };
                                return callbck_create(to_ret);
                            } else {
                                //console.log('create test case: ' + body);
                                body = JSON.parse(body);

                                if (body.CreateResult.Object != undefined) {
                                    create_id = body.CreateResult.Object.ObjectID;
                                }
                                else {
                                    create_id = 0;
                                }
                                to_ret = {
                                    json: json,
                                    i: i,
                                    j: j,
                                    k: k,
                                    duration: duration,
                                    line: line,
                                    id: create_id,
                                    status: status,
                                    folder_id: folder_id,
                                    user_story: user_story
                                };
                                return callbck_create(to_ret);
                            }
                        });
                },
                updateTestCaseResult: function (test_case_id, test_case_result_id, duration, name, status, user_story, i, j, k, testset, callbck) {
                    //console.log('update TCR fxn: ' + testset + ' tc: ' + test_case_id + ' tcrid ' + test_case_result_id);
                    if (duration == undefined) {
                        duration = 0;
                    }
                    if ((duration != undefined) && (duration > 9999999999)) {
                        duration = 9999999999;
                    }
                    if (status == 'passed') {
                        status = 'Pass';
                    } else if (status == "failed") {
                        status = 'Fail';
                    } else if (status == "skipped") {
                        status = 'Inconclusive';
                        duration = 0;
                    }

                    var d = new Date();
                    var date = d.toISOString();
                    var request = require("request-promise");
                    var to_return;
                    var options = {
                        method: 'POST',
                        url: baseUrl + 'testcaseresult/' + test_case_result_id,
                        headers: {
                            zsessionid: zsessionid
                        },
                        proxy: proxy,
                        body: '{\n' +
                        '    "testcaseresult":\n' +
                        '        {\n' +
                        '            "Build":"' + name + '",\n' +
                        '            "Duration":"' + duration + '",\n' +
                        '            "Date":"' + date + '",\n' +
                        '            "TestCase":"/testcase/' + test_case_id + '",\n' +
                        '            "Verdict":"' + status + '",\n' +
                        '            "TestSet":"' + testset + '"\n' +
                        '        }\n' +
                        '}'
                    };
                    request(options)
                        .then(function (body,error) {
                            if (error) {
                                console.log("Rally error: " + error);
                            } else {
                                //console.log('update test case result: ' + body);
                                to_return = {
                                    i: i,
                                    j: j,
                                    k: k
                                };
                                return callbck(to_return);
                            }
                        });
                },
                updateTestCase: function (test_case_id, user_story, i, j, body, json, test_case_name, test_case_description, glb_folder_id, line, duration, status, owner, testset, callbck) {
                    //console.log('in update TC fxn');
                    var request = require("request-promise");
                    var options = {
                        method: 'POST',
                        url: baseUrl + '/testcase/' + test_case_id,
                        headers: {zsessionid: zsessionid},
                        proxy: proxy,
                        body: '{\n' +
                        '    "testcase":\n        {\n' +
                        '            "WorkProduct":"' + user_story + '",\n' +
                        '            "Owner":"' + owner + '"\n' +
                        '            "Method":"'+method+'",\n' +
                        '        }\n' +
                        '}'
                    };
                    request(options)
                        .then(function (body,error) {
                            var to_return;
                            if (error) {
                                console.log('error occurred: ' + error);
                                callbck();
                            } else {
                                //console.log('updated test case: ' + body);
                                body = JSON.parse(body);
                                to_return = {
                                    test_case_id: test_case_id,
                                    user_story: user_story,
                                    i: i,
                                    j:j,
                                    body:body,
                                    json:json,
                                    test_case_name: test_case_name,
                                    test_case_description: test_case_description,
                                    glb_folder_id:glb_folder_id,
                                    line:line,
                                    duration: duration,
                                    status:status
                                };
                                callbck(to_return);
                            }
                        });
                },
                updateTestSet: function(testset, testcase, status, duration, glb_test_case_id, glb_folder_id, json, i, j, k, callbck){
                    //TODO: add error handling here - if testset is null, callback
                    //console.log('in update TS fxn');
                    if(testset == ''){
                        to_return = {
                            test_set_id:'',
                            status:status,
                            duration:duration,
                            glb_test_case_id:glb_test_case_id,
                            glb_folder_id:glb_folder_id,
                            json:json,
                            i:i,
                            j:j,
                            k:k
                        }
                        callbck(to_return);
                    } else {
                        var request = require("request-promise");
                        var options = {
                            method: 'POST',
                            url: 'https://rally1.rallydev.com/slm/webservice/v2.x/TestSet/' + testset + '/TestCases/add?fetch=true',
                            headers: {zsessionid: zsessionid},
                            proxy: proxy,
                            body: '{"CollectionItems":[{"_ref":"/testcase/' + testcase + '"}]}'
                        };
                        var to_return;
                        request(options)
                            .then(function (body, error) {
                                //console.log('updated test set: ' + body);
                                to_return = {
                                    test_set_id: testset,
                                    status: status,
                                    duration: duration,
                                    glb_test_case_id: glb_test_case_id,
                                    glb_folder_id: glb_folder_id,
                                    json: json,
                                    i: i,
                                    j: j,
                                    k: k
                                }
                                callbck(to_return);
                            });
                    }
                }
            }
        };
        module.exports = new RallyHelper();
    }());