/* global Bdf,$$,Diagnostic */

Diagnostic.UrlScan = {};

Diagnostic.UrlScan.URL_MAX = 5;
Diagnostic.UrlScan.INTERVAL = 2000;

Diagnostic.UrlScan.load = function () {
    var containerId = Bdf.generateId();
    var uncheckedArray = new Array();
    $$("layout_main").html(Bdf.render("diagnostic:urlscan", {
        containerId: containerId,
        modeLocKey: "_ link.diagnostic.urlscan_selection"
    }));
    $$(containerId, "body").on("click", $$.toCssSelector({action: "deployFiches"}), function () {
        let generatedId = this.dataset.generatedId;
        let $fichesRow = $$(generatedId, "fiches");
        if ($fichesRow.hasClass("hidden")) {
            $fichesRow.removeClass("hidden");
        } else {
            $fichesRow.addClass("hidden");
        }
    });
    $.ajax ({
        url: Bdf.URL + "administration",
        data: {
            cmd: "UrlScan",
            json: "urlinfos",
            fiches: "selection"
        },
        dataType: "json",
        success: function (data, textStatus) {
            if ((!data.urlInfos) || (data.urlInfos.array.length === 0)) {
                $$(containerId, "body").html(Bdf.render("diagnostic:urlscan-none", {}));
            } else {
                _completeData(data);
                $$(containerId, "body").html(Bdf.render("diagnostic:urlscan-table", data));
                _checkMissingReports();
            }
        }
    });
    
    function _completeData(data) {
        let tempArray = new Array();
        let ficheMap = data.urlInfos.ficheMap;
        for(let info of data.urlInfos.array) {
            info._generatedId = Bdf.generateId();
            Diagnostic.UrlScan.completeInfo(info);
            if (ficheMap) {
                Diagnostic.UrlScan.completeFichesInfo(info, ficheMap, data.urlInfos.fieldMap);
            }
            if (info._category === "unchecked") {
                tempArray.push(info.url);
                if (tempArray.length === Diagnostic.UrlScan.URL_MAX) {
                    uncheckedArray.push(tempArray);
                    tempArray = new Array();
                }
            }
        }
        if (tempArray.length > 0) {
            uncheckedArray.push(tempArray);
        }
        data.urlInfos.array.sort(function (info1, info2) {
            if (info1._sortKey < info2._sortKey) {
                return -1;
            } else if (info1._sortKey > info2._sortKey) {
                return 1;
            } else if (info1.url < info2.url) {
                return -1;
            } else if (info1.url > info2.url) {
                return 1;
            } else {
                return 0;
            }
        });
    }
    
    function _checkMissingReports() {
        var i = 0;
        var length = uncheckedArray.length;
        setTimeout(__ajax, Diagnostic.UrlScan.INTERVAL);

        function __ajax() {
            if (i < length) {
                let urlArray = uncheckedArray[i];
                $.ajax ({
                    url: Bdf.URL + "administration",
                    data: {
                        cmd: "UrlTest",
                        json: "urlinfos",
                        url: urlArray
                    },
                    traditional: true,
                    dataType: "json",
                    method: "POST",
                    success: function (data, textStatus) {
                        for(let info of data.urlInfos.array) {
                            _updateInfo(info);
                        }
                    }
                });
                i++;
                setTimeout(__ajax, Diagnostic.UrlScan.INTERVAL);
            }
        }
    }
    
    function _updateInfo(info) {
        Diagnostic.UrlScan.completeInfo(info);
        let $row = $$(containerId, "body", {url: info.url});
        $$($row, {role: "category"}).html(Bdf.render("diagnostic:urlscan-category", info));
        $$($row, {role: "link"}).html(Bdf.render("diagnostic:urlscan-link", info));
        $$($row, {role: "report"}).html(Bdf.render("diagnostic:urlscan-report", info));
    }
    
};

Diagnostic.UrlScan.completeFichesInfo = function (info, ficheMap, fieldMap) {
    for(let fiche of info.ficheArray) {
        let completeFiche = ficheMap[fiche.key];
        fiche._fiche = completeFiche;
        let fieldTitleArray = new Array();
        for(let field of fiche.fieldArray) {
            fieldTitleArray.push(fieldMap[completeFiche.corpus + "/" + field]);
        }
        fiche._fieldTitleArray = fieldTitleArray;
    }
};

Diagnostic.UrlScan.completeInfo = function (info) {
    var result = Diagnostic.UrlScan.extractSortKey(info.url);
    var sortKey = result[0];
    info._sortKey = sortKey;
    info._prefix = result[1];
    var finalRedirection = _getFinalRedirection();
    var significantRedirection = _isSignificantRedirection();
    var finalState = _getFinalState();
    info._finalRedirection = finalRedirection;
    info._significantRedirection = significantRedirection;
    info._category = _getCategory();
    info._linkType = _getLinkType();
    info._finalResponse = _getFinalResponse();
    info._errorLocKey = _getErrorLocKey();

    
    function _getFinalRedirection() {
        if ((info.report) && (info.report.redirectionArray)) {
            return info.report.redirectionArray[info.report.redirectionArray.length - 1];
        } else {
            return null;
        }
    }
    
    function _getFinalState() {
        if (!info.report) {
            return "";
        }
        if (finalRedirection) {
            return finalRedirection.state;
        } else {
            return info.report.state;
        }
    }
    
    function _getFinalResponse() {
        if (finalState === "http_error") {
            if (finalRedirection) {
                return finalRedirection.response;
            } else {
                return info.report.response;
            }
        } else {
            return null;
        }
    }
    
    function _getCategory() {
        if (!info.report) {
            return "unchecked";
        }
        if (info.report.state === "ok") {
            return "valid";
        }
        if (finalRedirection) {
            if (finalRedirection.state !== "ok") {
                return "error";
            } else if (significantRedirection) {
                return "redirection";
            } else {
                return "valid";
            }
        }
        if ((info.report.response) && (info.report.response.code >= 500)) {
            return "servererror";
        } else {
            return "error";
        }
    }
    
    function _isSignificantRedirection() {
        if (!finalRedirection) {
            return false;
        }
        if (finalRedirection.state !== "ok") {
            return false;
        }
        let destinationKey = Diagnostic.UrlScan.extractSortKey(finalRedirection.url)[0];
        if (destinationKey.startsWith(sortKey)) {
            return false;
        } else {
            return true;
        }
    }
    
    function _getLinkType() {
        switch(finalState) {
            case "":
                return "none";
            case "malformed":
            case "relative":
            case "unknown_protocol":
                return "none";
            case "ok":
                if (significantRedirection) {
                    return "redirection";
                } else {
                    return "valid";
                }
            case "not_found":
                return "broken";
            default:
                return "error";
        }
    }
    
    function _getErrorLocKey() {
        switch(finalState) {
            case "bad_http":
                return "_ label.diagnostic.error_badhttp";
            case "http_error":
                return "_ label.diagnostic.error_httpcode";
            case "malformed":
                return "_ label.diagnostic.error_malformedurl";
            case "missing_redirection":
                return "_ label.diagnostic.error_missingredirection";
            case "not_found":
                return "_ label.diagnostic.error_brokenurl";
            case "redirection_limit":
                return "_ label.diagnostic.error_redirectionlimit";
            case "relative":
                return "_ label.diagnostic.error_relativeurl";
            case "timeout":
                return "_ label.diagnostic.error_timeout";
            case "unknown_protocol":
                return "_ label.diagnostic.error_unknownprotocol";
            case "unreachable":
                return "_ label.diagnostic.error_unreachable";
            default:
                return "";
        }
    }
    
};

Diagnostic.UrlScan.extractSortKey = function (url) {
    var key = url;
    var prefix = "";
    if (key.startsWith("http://")) {
        key = key.substring(7);
        prefix = "http://";
    } else if (key.startsWith("https://")) {
        key = key.substring(8);
        prefix = "https://";
    }
    if (key.startsWith("www.")) {
        key = key.substring(4);
        prefix = prefix + "www.";
    }
    return [key, prefix];
};
