/*
This file is part of SystemTestPortal.
Copyright (C) 2017  Institute of Software Technology, University of Stuttgart

SystemTestPortal is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

SystemTestPortal is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with SystemTestPortal.  If not, see <http://www.gnu.org/licenses/>.
*/

$.getScript("/static/js/util/common.js");
$.getScript("/static/js/util/ajax.js");
$.getScript("/static/js/project/tests.js");

// testsequence contains the original testsequence that was edited. It is used to check
// for changes in the data.
var testsequence;

// Button Assignment
function assignButtonsTestSequence() {
//List
    $("#buttonNewTestSequence").click(newTestSequence);
    $("#buttonNewTestSequenceDisabled").click(showSigninHint);
    $("#buttonFirstTestSequence").click(newTestSequence);
    $("#buttonNewLabel").click(function (event) { /* nothing yet */
    });
    $(".testSequenceLine").click(showTestSequence);
    $(".filterBadge").click(filterTestSequenceListWithBadge);
//Show
    $("#buttonBack").click(backToTestSequenceList);
    $("#buttonDeleteTestSequence").click(deleteTestSequence);
    $("#buttonEdit").click(editTestSequence);
    $("#buttonHistory").click(showTestSequenceHistory);
//$("#buttonRevertConfirmed")  .click(function (event) { revertTestSequence(event); });
//History
    $("#buttonBackToSequence").click(backToTestSequence);
    $(".versionLine").click(showTestSequenceVersion);
//New
    $("#buttonAbort").click(backToTestSequenceList);
    $("#testSequenceEdit").on("submit", saveTestSequence);
    $("#buttonSaveNew").click(saveTestSequence);
//Edit
    $("#buttonSave").click(updateTestSequence);
    $("#buttonAbortEdit").click(backToTestSequence);
//Execute
    $("#buttonExecute").click(execute);

}

//Adds Enter-key-handler for name textfield, to prevent random actions for enter key
function assignEventsToNameTextField() {
    $("#inputTestSequenceName").keydown(function(event){
        if(event.keyCode === 13){
            event.preventDefault();
            $("#inputTestSequenceDescription").focus();
        }
    });
}

/* AJAX-Functions */
/* loads the new test sequence form */
function newTestSequence(event) {
    ajaxRequestFragment(event, "new", "", "GET");
}

/*show sign in hint if not signed in and button is pressed*/
function showSigninHint(event) {
    event.preventDefault();
    $("#signin-link").tooltip('show');
}

/* loads the chosen test sequence */
function showTestSequence(event) {
    ajaxRequestFragment(event, getProjectTabURL().appendSegment(event.target.id).toString(), "", "GET");
}

/* loads the chosen test sequence version*/
function showTestSequenceVersion(event) {
    var url = getTestURL().toString();
    // Get version number. When clicking on an element that is in the .versionLine, check the parent of
    // this element until the parent is the versionLine with the id
    var ind = event.target.id;
    while (ind === "") {
        event.target = event.target.parentNode;
        ind = event.target.id;
    }
    ajaxRequestFragmentWithHistory(event, url, {version: ind}, "GET", url + "?version=" + ind);
}

/* saves the test sequence */
function saveTestSequence(event) {
    var history = currentURL().removeLastSegments(1).toString() + "/";
    ajaxRequestFragmentWithHistory(event, "save", getDataNewTestSequence(), "POST", history);
}

/* deletes a test sequence */
function deleteTestSequence(event) {
    var history = currentURL().removeLastSegments(1).toString() + "/";
    $('#deleteTestSequence').on('hidden.bs.modal', function () {
        ajaxRequestFragmentWithHistory(event, currentURL().toString(), "", "DELETE", history);
    }).modal('hide');
}

/* edits a test sequence */
function editTestSequence(event) {
    var ver =$('#inputTestsequenceVersion').find("option:selected").val();
    ajaxRequestFragment(event, currentURL().appendSegment("edit").toString(), { version: ver }, "GET");
}

/* revert test sequence to selected version */
function revertTestSequence(event) {
    // not yet implemented
}

// This function is called when clicking on the save button in the edit test sequence
// screen. It checks if there are any changes to the data of a test sequence.
// If only the name changed, the sequence is saved directly. If the metadata was changed
// the modal with the commit message is opened.
function checkForChanges() {
    // If only name of the test sequence changed, dont open commit modal but save directly
    if (onlyTestSequenceNameChanged()) {
        handleEdit(null, false);
    } else {
        $("#modal-testsequence-save").modal('show');
    }
}

// onlyTestSequenceNameChanged checks whether there was any changes to the input
// of the metadata of the edited test sequence.
// Returns true if no metadata was changed. Else returns false.
function onlyTestSequenceNameChanged() {
    var onlyTSNameChanged = true;
    if (testsequence.SequenceVersions[0].Description !== $('#inputTestSequenceDescription').val().trim()) {
        onlyTSNameChanged = false;
    }
    if (preconditionsChanged()) {
        onlyTSNameChanged = false;
    }
    // There were no cases previously and during editing some cases were added
    if ((!testsequence.SequenceVersions[0].Cases && $(".testCaseInTestSequence").length > 0)
        // or the sequence contained cases and the number of cases changed
        || (testsequence.SequenceVersions[0].Cases &&
            ($(".testCaseInTestSequence").length !== testsequence.SequenceVersions[0].Cases.length))) {

        onlyTSNameChanged = false;
    }

    // Check if the cases in the sequence have changed
    if (testsequence.SequenceVersions[0].Cases) {
        $(".testCaseInTestSequence").each(function (index) {
            if (!testsequence.SequenceVersions[0].Cases[index] || this.id !== testsequence.SequenceVersions[0].Cases[index].Name) {
                onlyTSNameChanged = false;
            }
        });
    }
    return onlyTSNameChanged;
}



/* saves the test sequence */
function updateTestSequence(event) {
    $('#modal-testsequence-save').on
    (
        'hidden.bs.modal',
        handleEdit(event, $('#minorUpdate').is(':checked'))
    ).modal('hide');
}

/* show test sequence history */
function showTestSequenceHistory(event) {
    ajaxRequestFragment(event,currentURL().appendSegment("history").toString(), "", "GET");
}

/* steps back to the test sequence  */
function backToTestSequence(event) {
    var requestURL = getTestURL().toString();
    ajaxRequestFragment(event, requestURL, "", "GET");
}

/* steps back to the test sequence list */
function backToTestSequenceList(event) {
    var requestURL = getProjectURL().appendSegment("testsequences").toString() + "/";
    ajaxRequestFragment(event, requestURL, "", "GET");
}

// handleEdit either updates the current version or saves the edited version as newest version, depending
// on the handling parameter
function handleEdit(e, isMinor) {

    /* stop form from submitting normally */
    if (e !== null && e !== undefined) {
        e.preventDefault();
    }

    var url = currentURL().removeLastSegments(1).toString();
    /* Send the data using post with element ids*/
    var posting = $.ajax({
        url: url + "/update?fragment=true",
        type: "PUT",
        data: getDataEdit(isMinor)
    });
    console.log(getDataEdit(isMinor))
    /* Alerts the results */
    posting.done(function (response) {
        var historyText = currentURL().takeFirstSegments(4).appendCodedSegment(posting.getResponseHeader("newName")).toString();
        $('#tabTestsequences').empty().append(response);
        history.pushState('data', '', historyText);
    }).fail(function (response) {
        $("#modalPlaceholder").empty().append(response.responseText);
        $('#errorModal').modal('show');
    });
}

// getDataNewTestSequence return an array with information of the new test sequence
function getDataNewTestSequence() {
    var testcases = gatherTestCasesInSequenceIDs();
    return {
        inputTestSequenceName: $('#inputTestSequenceName').val(),
        inputTestSequenceDescription: $('#inputTestSequenceDescription').val(),
        inputTestSequencePreconditions: JSON.stringify(getPreconditions()),
        inputTestSequenceTestCase: testcases,
        inputTestSequenceLabels: JSON.stringify(getTestSequenceLabelsInput()),
        inputSUTVersion: $('#inputSUTVersion').val(),
        inputTestSequenceVersion: $('#inputTestSequenceVersion').val(),
        inputTestSequenceTime: $('#inputTestSequenceTime').val()
    }
}

// getTestSequenceLabelsInput returns a list with the selected labels
function getTestSequenceLabelsInput() {
    // testSequenceLabels contains the the labels of the test case
    var testSequenceLabels = [];
    //  Get index of selected labels in dropdown
    var labelsValues = $('#labels').find('option:selected').map(function(a, item){return item.value;});

    // Add the selected labels to testSequenceLabels
    $.each(labelsValues, function(index, value) {
        testSequenceLabels.push(projectLabels[value])
    });

    return testSequenceLabels;
}

// getDataEdit return an array with information of the test sequence to edit
function getDataEdit(isMinor) {
    var testcases = gatherTestCasesInSequenceIDs();
    return {
        isMinor: isMinor,
        inputCommitMessage: $('#inputCommitMessage').val(),
        version: "{{ GetTestSequenceVersion.VersionNr }}",
        inputTestSequenceName: $('#inputTestSequenceName').val(),
        inputTestSequenceDescription: $('#inputTestSequenceDescription').val(),
        inputTestSequencePreconditions: JSON.stringify(getPreconditions()),
        inputTestSequenceTestCase: testcases,
        inputTestSequenceLabels: JSON.stringify(getTestSequenceLabelsInput()),
        inputSUTVersion: $('#inputSUTVersion').val(),
        inputTestSequenceVersion: $('#inputTestSequenceVersion').val(),
        inputTestSequenceTime: $('#inputTestSequenceTime').val()
    }
}

// collects the test case IDs for the test sequence
function gatherTestCasesInSequenceIDs() {
    var testcases = "";
    $(".testCaseInTestSequence").each(function () {
        testcases = testcases + this.id + "/";
    });
    return testcases.slice(0, -1);
}

/* loads the start page of the test seq execution */
function execute(event) {
    ajaxRequestFragment(event, currentURL().appendSegment("execute").toString(), "", "GET");
}

// filters the list to show only elements with the selected badge
function filterTestSequenceListWithBadge(event) {
    $(".tooltip").tooltip("hide");

    event.preventDefault();

    var filters = getFilterFromSession();
    filters = handleFilterOnFilters(event.target.id, filters);

    var requestURL = getProjectURL().appendSegment("testsequences").toString() + "/";
    requestURL = requestURL + "?fragment=true&filter=";
    requestURL = requestURL + JSON.stringify(filters);
 
    var posting = $.get(requestURL);

    /* Alerts the results */
    posting.done(function (response) {
        $('#tabarea').empty().append(response);
    }).fail(function (response) {
        $("#modalPlaceholder").empty().append(response.responseText);
        $('#errorModal').modal('show');
    });

    return false;
}

function assignPreconditionInputListener() {
    document.getElementById('preconditionInput').addEventListener('keypress', function (e) {
        var key = e.which || e.keyCode;
        if (key === 13) { // 13 is enter
          addPrecondition(e);
        }
    });

    $("#preconditionAdder").click(function (event) {
        addPrecondition(event);
    });

    $('.deletePrecondition').click(function (event) {
        deletePrecondition(event);
    });
}

function addPrecondition(event) {
    event.preventDefault();
    text = document.getElementById('preconditionInput').value.trim(); 

    if (text.length > 0) {
        var preconditions = document.getElementById('preconditionsList');
        var li = document.createElement("li");
        li.className = 'list-group-item preconditionItem';
    
        var span = document.createElement("span");
        span.appendChild(document.createTextNode(text));
        li.appendChild(span);

        var button = document.createElement("button");
        button.className = "btn btn-danger mr-2 deletePrecondition pull-right";
        button.addEventListener("click", function(event) {
            deletePrecondition(event);
        });
        button.innerHTML = "Delete";

        li.appendChild(button);
        li.id = $('#preconditionsList').length

        preconditions.appendChild(li)
         
    }
    document.getElementById('preconditionInput').value = "";
}

function deletePrecondition(event) {
    event.preventDefault();

    var li = event.target.parentNode;
    li.remove();
}

function getPreconditions() {
    var arr = $('.preconditionItem').find('span:first').map(function(){
        return $(this).text();
    }).get();
    return arr;
}

function preconditionsChanged() {
    return testsequence.SequenceVersions[0].Preconditions !== getPreconditions();
}