$(document).ready(function runTestEnv($) {
    var url = $('#url').html();
    var key = $('#key').html();

    var total = 0;
    var empty = 0;
    var success = 0;
    var failed = 0;
    var ajaxTimeout = 120000;
    var ajaxDelay = 60000;

    var enableDebug = true;

    prepareTests();

    function bindClicks(selector) {
        $(selector).click(function reRunClicked() {
            reRunClickEvent(this);
        });
    }

    function prepareTests() {
        var functionsList = $('#functions').html();
        var functions = JSON.parse(functionsList);

        debug(functions);
        setTotal(functions.length);

        runAllTests(functions);
    }

    function runAllTests(functions) {
        $.each(functions, function prepareTest(index, value) {
            var requestUrl = 'http://soap.encrypted.pl/unit.php?functionsBase=' + value;

            var encoded = encodeURIComponent(url);
            requestUrl += '&url=' + encoded;
            requestUrl += '&key=' + key;

            var thisTimeout = ajaxDelay * index;
            debug(thisTimeout / 1000 + 's timeout for AJAX on ' + requestUrl);

            setTimeout(function () {
                runTest(requestUrl, value);
            }, thisTimeout);
        });
    }

    function reRunClickEvent(element) {
        var url = $(element).data("url");
        var functionName = $(element).data("function");

        reRunTest(url, functionName);
    }

    function reRunTest(requestUrl, functionName) {
        deleteTest(functionName);
        runTest(requestUrl, functionName);
    }

    function runTest(requestUrl, functionName) {
        debug('AJAX start: ' + requestUrl);

        $.ajax({
            type: "GET",
            url: requestUrl,
            timeout: ajaxTimeout,
            success: function (data) {
                debug('AJAX end: ' + requestUrl);
                displayFrontend(data, functionName, requestUrl);
            },
            error: function (xhr, textStatus, errorThrown) {
                debug('AJAX failed: ' + requestUrl + ' with error: ' + errorThrown);
                var data = [];
                data.status = 0;
                data.error = errorThrown;
                displayFrontend(data, functionName, requestUrl);
            }
        });
    }

    function deleteTest(functionName) {
        $('#result-' + functionName).remove();
        removeFailed();
    }

    function displayFrontend(data, functionName, requestUrl) {
        if (data.status == 1) {
            addSuccess(data);
            var html = '<li id="result-' + functionName + '"><button class="btn btn-success">'
                + functionName + '</button> '
                + data.size + ' items on request url: ' + requestUrl + '</li>';
        } else {
            if (data.error == 'Empty response') {
                addEmpty();
                var html = '<li id="result-' + functionName + '"><button class="btn btn-warning">'
                    + functionName + '</button> '
                    + 'empty on request url: ' + requestUrl + '</li>';
            } else {
                addFailed(data);
                var html = '<li id="result-' + functionName + '"><button class="btn btn-danger">'
                    + functionName + '</button> '
                    + data.error + ' on request url: ' + requestUrl
                    + ' <button id="result-' + functionName + '-rerun" class="btn" ' +
                    'data-url="' + requestUrl + '" ' +
                    'data-function="' + functionName +  '">Rerun test</button>' + '</li>';
            }
        }

        $('#test-results').append(html);
        bindClicks('#result-' + functionName + '-rerun');
    }

    function setTotal(countedTotal) {
        total = countedTotal;
        updateInfo();
    }

    function addSuccess() {
        success++;
        updateInfo();
    }

    function addEmpty() {
        empty++;
        updateInfo();
    }

    function addFailed() {
        failed++;
        updateInfo();
    }

    function removeFailed() {
        failed = failed - 1;
        updateInfo();
    }

    function updateInfo() {
        var percentageDone = ((failed + success + empty) * 100) / total;
        var percentageSuccess = (percentageDone == 0) ? 100 : (((success + empty) * 100) / (failed + empty + success));

        var html = percentageDone + '% test done with score <strong>'
            + percentageSuccess + '% sucess</strong>';
        html += '<br/>Success: ' + success + '/' + total;
        html += '<br/>Empty: ' + empty + '/' + total;
        html += '<br/>Failed: ' + failed + '/' + total;

        $('#info').html(html);

        if (percentageDone == 100) {
            $('#spinner').hide();
        }
    }

    function debug(text) {
        if (enableDebug) {
            console.log(text);
        }
    }
});