/*
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");

// sutVersionData contains all variants and versions of the system under test
var sutVersionData;
// testCaseVersionData contains all the variants and versions of a test case.
// It is used to add versions which only exist in the test case but not in the sut anymore to the list of versions.
var testCaseVersionData;
// selectedVersions is an array of variant objects
var selectedVersions = {};

// Send a request to get the sut variants and versions of the project
var url = getProjectURL().appendSegment("versions").toString();
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.send();


// Update the variants and versions
xmlhttp.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
        sutVersionData = JSON.parse(this.responseText);
        // Fill the drop down menu with the variants of the system under test
        fillVariants(sutVersionData, "#inputTestCaseSUTVariants");
        // Update the version list with the versions of the selected variant
        updateVersionSelectionList(null);
    }
};

// Set Listeners for variants and versions
setVariantOnFocusListener();
setVersionsOnClickListener();

// Update variants and versions in dropdown and list when the
// modal with sut variants and versions is closed
$("#modal-manage-versions").on('hidden.bs.modal', function(e) {
    xmlhttp.open("GET", url, true);
    xmlhttp.send();
});

/* Save and update the variants and the versions on drop down selection change*/
function setVariantOnFocusListener() {
    var previousVariantKey;

    $("#inputTestCaseSUTVariants").on('focus', function () {
        // Store the current value on focus and on change
        previousVariantKey = $("#inputTestCaseSUTVariants").val();
    }).change(function() {
        updateVersionSelectionList(previousVariantKey);

        // Make sure the previous value is updated
        previousVariantKey = $("#inputTestCaseSUTVariants").val();
    });
}

/* Saves the currently selected versions */
function setVersionsOnClickListener() {
    $('#inputTestCaseSUTVersions').on('change', function () {
        saveSelectedVersions($("#inputTestCaseSUTVariants").val());
    });
}


/* Updates the versions in the list based on the currently selected variant in the
 * drop down menu */
function updateVersionSelectionList(previousVariantKey) {
    // save selected versions of the previous selected variant
    if (previousVariantKey != null) {
        saveSelectedVersions(previousVariantKey);
    }

    // Get the newly selected variant and populate the versions list based on the new variant
    var selectedVariantKey = $('#inputTestCaseSUTVariants').val();
    populateVersionSelectionList(selectedVariantKey)
}

/* saves the versions of the previously selected variant */
function saveSelectedVersions(selectedVariantKey) {
    var selectedVersionsList = [];
    $.each($('#inputTestCaseSUTVersions').val(), function(key, versionName) {
        selectedVersionsList.push({Name:versionName});
    });
    selectedVersions[selectedVariantKey] = {Name:selectedVariantKey,Versions:selectedVersionsList};
}

/* fill version list with the versions of the selected variant*/
function populateVersionSelectionList(selectedVariantKey) {
    var versionList = $('#inputTestCaseSUTVersions');

    // remove all previously shown elements
    versionList.empty();
    if (sutVersionData !== null && sutVersionData[selectedVariantKey] !== null) {
        // add versions of selected variant to list
        $.each(sutVersionData[selectedVariantKey].Versions, function(key, version) {
            var listElement;
            if (selectedVersions[selectedVariantKey] != null && containsVersion(version, selectedVersions[selectedVariantKey].Versions)) {
                listElement = ($("<option selected></option>")
                    .html('<span>' + version.Name + '</span>'));
            } else {
                listElement = ($("<option></option>")
                    .html('<span>' + version.Name + '</span>'));
            }
            versionList.append(listElement);
        });
    }

    // Add deprecated versions that exist in the test case but not in the system anymore to the list
    if(testCaseVersionData != null && testCaseVersionData[selectedVariantKey] != null) {
        $.each(testCaseVersionData[selectedVariantKey].Versions, function(key, version) {
            var listElement;
            // Only add if the version is not yet in the list of versions
            if (selectedVersions[selectedVariantKey] != null && !containsVersion(version, sutVersionData[selectedVariantKey].Versions)) {
                // Check if the version is selected
                if (containsVersion(version, selectedVersions[selectedVariantKey].Versions)) {
                    listElement = ($("<option selected></option>")
                        .html('<span>' + version.Name + '</span>'));
                } else {
                    listElement = ($("<option></option>")
                        .html('<span>' + version.Name + '</span>'));
                }
                versionList.append(listElement);
            }
        });
    }
}

// containsVersion checks if a version with the same name already exists in an array of version objects.
// returns true if it exists and false it it does not exist
function containsVersion(version, versionList) {
    var containsVersion = false;
    if (versionList !== null && versionList.length > 0) {
        versionList.forEach(function(ver) {
            if (ver.Name === version.Name) {
                containsVersion = true;
            }
        });
    }
    return containsVersion;
}
