var app = angular.module('ScubaApp', ['ui.bootstrap']);

app.controller('mainController', function ($scope, $filter, $sce, $timeout) {

    $scope.complianceTests = 0;
    $scope.complianceFailures = 0;
    $scope.vulnerabilitiesTests = 0;
    $scope.vulnerabilitiesFailures = 0;
    $scope.complianceReadiness = 0;

    //Page
    $scope.MAX_EVENTS_IN_PAGE = 15;
    $scope.activePage = { value: 1 };
    $scope.maxPages = 1;
    $scope.fromIndex = 0;
    $scope.toIndex = 0;
    $scope.numberOfAllTestsToShowInTable = 0;

    $scope.INVALID_ASSESSMENT_SCORE = "0.0";
    $scope.MAX_REMEDIATION_TOOLTIP_LENGTH = 100;
    $scope.showErrorsSummary = false;

    $scope.COLUMNS = {
        'Test': 'test',
        'Category': 'category',
        'Compliance': 'regulation',
        'Result': 'severityText'
    }

    $scope.sortType = $scope.COLUMNS.Result;
    $scope.sortReverse = true;
    
    $scope.GA_Address = "";
    $scope.GA_DefaultLink = "https://www.imperva.com/docs/gated/scuba_version.html";

    $scope.emptyScanResultsFound = false;

    $scope.STATUSES = {
        'Failed': {
            counter: 0,
            percentage: 0,
            customClass: "fa fa-times-circle",
            tableStyle: { 'color': 'red' },
            doughnutBackground: 'red',
            doughnutBackgroundHover: '#E95E4F'
        },
        'Passed': {
            counter: 0,
            percentage: 0,
            customClass: "fa fa-check-circle",
            tableStyle: { 'color': 'limegreen' },
            doughnutBackground: '#78BE20',
            doughnutBackgroundHover: '#B0E66B'
        },
        'Info': {
            counter: 0,
            percentage: 0,
            customClass: "fa fa-info-circle",
            tableStyle: { 'color': 'lightseagreen' },
            doughnutBackground: '#00A9E0',
            doughnutBackgroundHover: '#53D5FF'
        },
        'Error': {
            counter: 0,
            percentage: 0,
            customClass: "fa fa-exclamation-triangle",
            tableStyle: { 'color': 'orange' },
            doughnutBackground: '#E87722',
            doughnutBackgroundHover: '#F1AD7A'
        }
    }
    
    $scope.REGULATIONS = {
        'CIS': {
            count: 0,
            failures: 0,
            link: "https://www.cisecurity.org/"
        },
        'DISA (STIG)': {
            count: 0,
            failures: 0,
            link: "http://iase.disa.mil/stigs/Pages/index.aspx"
        }/*,
        'FISMA': {
            count: 0,
            failures: 0,
            link: "https://www.dhs.gov/fisma"
        },
        'HIPAA': {
            count: 0,
            failures: 0,
            link: "http://www.hhs.gov/hipaa/"
        },
        'PCI-DSS': {
            count: 0,
            failures: 0,
            link: "https://www.pcisecuritystandards.org/pci_security/"
        }*/
    };

    $scope.SEVERITIES = {
        'Critical': {
            failures: 0,
            customClass: "label label-danger",
            weight: 5
        },
        'High': {
            failures: 0,
            customClass: "label highLabel",
            weight: 4
        },
        'Medium': {
            failures: 0,
            customClass: "label label-warning",
            weight: 3
        },
        'Low': {
            failures: 0,
            customClass: "label label-info",
            weight: 2
        },
        'Info': {
            failures: 0,
            customClass: "label label-primary",
            weight: 1
        }
    };

    $scope.sortHeader = function (header) {
        $scope.sortType = header;
        $scope.sortReverse = !$scope.sortReverse
    }

    $scope.getAssessmentSeverityStyle = function (value) {
        return { 'width': Math.floor(value / $scope.STATUSES['Failed'].counter * 100).toString() + '%' };
    }

    $scope.hasRemediation = function (assessment) {
        return $scope.hasAssessmentFailedOrInfo(assessment) && assessment.remediation.length > 0;
    }

    $scope.hasAssessmentFailedOrInfo = function (assessment) {
        return $scope.hasAssessmentFailed(assessment) || $scope.hasAssessmentInfo(assessment);
    }

    $scope.hasAssessmentInfo = function (assessment) {
        return assessment.result == 'Info';
    }

    $scope.hasAssessmentFailed = function (assessment) {
        return assessment.result == 'Failed';
    }

    $scope.getAssessmentSeverityClass = function (assessment) {
        if (!$scope.hasAssessmentFailedOrInfo(assessment)) {
            return "label successBackground";
        }
        return $scope.SEVERITIES[assessment.severity].customClass;
    }

    $scope.setSeverityText = function (assessment) {
        assessment.severityText = $scope.hasAssessmentFailedOrInfo(assessment)? assessment.severity : "Passed";
    }

    $scope.updateRegulationStatus = function (assessment, hasAssessmentFailed) {
        for (var i in assessment.regulations) {
            try {
                if (hasAssessmentFailed) {
                    $scope.REGULATIONS[assessment.regulations[i]].failures++;
                }
                $scope.REGULATIONS[assessment.regulations[i]].count++;
            } catch (err) {
                console.log("Unknown regulation", assessment.regulations[i]);
            }
        }
    }

    $scope.updateFailedSeveritiesCounters = function (assessment) {
        try {
            $scope.SEVERITIES[assessment.severity].failures++;
        } catch (err) {
            console.log("Unknown severity", assessment.severity);
        }
    }

    $scope.updateStatistics = function () {
        $scope.normalizeAndUpdateCounters();

        var totalPercentage = 0;
        var maxPercentage = 0;
        for (var result in $scope.STATUSES) {
            $scope.STATUSES[result].percentage = $scope.getResultsPercentage($scope.STATUSES[result].counter);
            totalPercentage += $scope.STATUSES[result].percentage;
            maxPercentage = Math.max(maxPercentage, $scope.STATUSES[result].percentage);
        }

        var diff = 100 - totalPercentage;
        for (var result in $scope.STATUSES) {
            if ($scope.STATUSES[result].percentage == maxPercentage) {
                $scope.STATUSES[result].percentage += diff;
                break;
            }
        }
    }

    $scope.isRegulationTest = function (assessment) {
        return assessment.regulations.length > 0;
    }

    $scope.isCVE = function (assessment) {
        return assessment.test.substring(0, 4) == "CVE-";
    }

    $scope.setCVELink = function (assessment) {
        if ($scope.isCVE(assessment)) {
            if (assessment.test.length > 13) {
                assessment.cveLink = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-" + assessment.test.substring(4, 13);
                assessment.cveName = assessment.test.substring(0, 13);
            }
        }
    }
    $scope.normalizeRemediation = function (assessment) {
        if (assessment.remediation.slice(-1) == ".") {
            assessment.remediation = assessment.remediation.substring(0, assessment.remediation.length - 1);
        }
    }

    $scope.isVulnerability = function (assessment) {
        return assessment.cveLink.length > 0;
    }

    $scope.normalizeAndUpdateCounters = function () {
        for (var i = $scope.results['assessments'].length - 1; i >= 0; i--) {
            var assessment = $scope.results['assessments'][i];
            $scope.normalizeAssessment(assessment);

            if (!$scope.showScanResult(assessment.result)) {
                continue;
            }

            try {
                $scope.STATUSES[assessment.result].counter++;
            } catch (err) {
                console.log("Unknown result", assessment);
                $scope.results['assessments'].splice(i, 1);
            }

            var hasAssessmentFailed = $scope.hasAssessmentFailed(assessment);
            var isRegulationTest = $scope.isRegulationTest(assessment);
            var isVulnerabilityTest = $scope.isVulnerability(assessment);

            if (isVulnerabilityTest) {
                $scope.vulnerabilitiesTests++;
                if (hasAssessmentFailed) {
                    $scope.vulnerabilitiesFailures++;
                }
            }
            
            if (isRegulationTest) {
                $scope.complianceTests++;
                if (hasAssessmentFailed) {
                    $scope.complianceFailures++;
                }
                $scope.updateRegulationStatus(assessment, hasAssessmentFailed);
            }

            if (hasAssessmentFailed) {
                $scope.updateFailedSeveritiesCounters(assessment);
            }

            if ($scope.showTestInTable(assessment)) {
                $scope.numberOfAllTestsToShowInTable++;
            }
        }
    }

    $scope.normalizeAssessment = function (assessment) {
        $scope.setCVELink(assessment);
        $scope.normalizeRemediation(assessment);
        $scope.setSeverityText(assessment);
        $scope.normalizeText(assessment);
        $scope.normalizeScore(assessment);
        assessment.regulations.sort();
    }

    $scope.getComplianceSummaryText = function (regulation) {
        if ($scope.hasRegulationFailed(regulation)) {
            return "Does not meet regulations";
        }
        if (!$scope.doesRegulationExist(regulation)) {
            return "No relevant tests detected";
        }
        return "Passed only a subset of tests";
    }

    $scope.getRiskSummaryText = function () {
        if ($scope.vulnerabilitiesFailures == 0) {
            return "No known vulnerabilities";
        }
        return $scope.GetNumberInThousands($scope.vulnerabilitiesFailures) + " vulnerabilit" + ($scope.vulnerabilitiesFailures == 1 ? "y" : "ies") + " detected";
    }

    $scope.getRiskSummaryClass = function () {
        if ($scope.vulnerabilitiesFailures == 0) {
            return "fa fa-check-circle successText";
        }
        return "fa fa-exclamation-triangle risk";
    }

    $scope.getNumberOfFailuresClass = function () {
        if ($scope.STATUSES['Failed'].counter == 0) {
            return "count successText";
        }
        return "count failureText";
    }

    $scope.setGauge = function () {
        var opts = {
            lines: 12,
            angle: 0,
            lineWidth: 0.4,
            pointer: {
                length: 0.75,
                strokeWidth: 0.042,
                color: '#1D212A'
            },
            limitMax: 'false',
            colorStart: '#2E1A47',
            colorStop: '#2E1A47',
            strokeColor: '#E87722',
            generateGradient: true
        };
        var target = document.getElementById('complianceGauge'),
            gauge = new Gauge(target).setOptions(opts);

        gauge.maxValue = 100;
        gauge.animationSpeed = 32;

        if ($scope.complianceTests == 0) {
            $scope.complianceReadiness = 100;
        } else if ($scope.complianceFailures == $scope.complianceTests) {
            // 0 mess up UI...
            $scope.complianceReadiness = 0.1;
        } else {
            $scope.complianceReadiness = Math.floor((($scope.complianceTests - $scope.complianceFailures) * 100) / $scope.complianceTests);
        }
        gauge.set($scope.complianceReadiness);
        gauge.setTextField(document.getElementById("gauge-text"));
    }

    $scope.GetNumberInThousands = function (number) {
        return $filter('number')(number, 0);
    }

    $scope.getScoreFormatting = function (number) {
        return $filter('number')(number, 1);
    }

    $scope.getExtraDetailsClass = function (assessment) {
        return assessment.showDetails ? "fa fa-minus-circle" : "fa fa-plus-circle";
    }

    $scope.tableRowClicked = function(assessment) {
        if ($scope.hasExtraDetails(assessment)) {
            assessment.showDetails = !assessment.showDetails;
        }
    }

    $scope.setAssessmentResults = function () {
        if (typeof IS_DEBUG !== 'undefined' && IS_DEBUG) {
            console.log("DEBUG ON");
            setRandomAssessmentResults();
        }

        try {
            $scope.results = ASSESSMENT_RESULTS;
        } catch (err) {
            $scope.emptyScanResultsFound = true;
            console.log("Unable to copy assessment results. Setting to default values.", err);
            $scope.setDefaultErrorValues();
        }
    }

    $scope.setDefaultErrorValues = function () {
        $scope.results = {
            'version': '3.0.2',
            'scanTimeMinutes': '00:00',
            'scanTimeEnd': '00:00:00 AM',
            'serverAddress': '255.255.255.255:65535',
            'user': 'user',
            'database': 'database',
            'databaseVersion': '0.0',
            'osVersion': '0.0',
            'utm': '?utm_medium=internal&utm_source=scuba_windows&utm_campaign=scuba_3.0.2',
            'hasPermissionsErrors': 'false',
            'adcContent': '',
            'dataRowsCountLimit': 500,
            'dataRowsProcessLimit': 50,
            'assessments' : []
        }
    }

    $scope.hasRegulationFailed = function (regulation) {
        return $scope.REGULATIONS[regulation].failures > 0;
    }

    $scope.doesRegulationExist = function (regulation) {
        return $scope.REGULATIONS[regulation].count > 0;
    }

    $scope.getRegulationStyle = function (regulation) {
        return $scope.hasRegulationFailed(regulation) ?
            { 'color': 'red' } : { 'color': '#00A9E0' };
    }

    $scope.getRegulationClass = function (regulation) {
        return $scope.hasRegulationFailed(regulation) ?
            "fa fa-times-circle failureText" : "fa fa-info-circle infoText";
    }

    $scope.getHeaderClass = function (_sortType) {
        if (_sortType != $scope.sortType) {
            return "sortButton";
        }
        return "sortButton selectedSortButton";
    }

    $scope.getSortClass = function (_sortType) {
        if (_sortType != $scope.sortType) {
            return "fa fa-sort pull-right";
        }
        if ($scope.sortReverse) {
            return "fa fa-sort-amount-desc pull-right";
        }
        return "fa fa-sort-amount-asc pull-right";
    }

    $scope.getResultsPercentage = function (counter) {
        var value = counter / $scope.results['assessments'].length * 100;
        if (value > 0 && value < 1) {
            value = 1;
        }
        return Math.round(value);
    }

    $scope.hasExtraDetails = function (assessment) {
        return assessment.details.length > 0 || assessment.description.length > 0 || assessment.cveLink.length > 0;
    }

    $scope.hasData = function (assessment) {
        return assessment.data.length > 1; // First data is the table's header
    }

    $scope.hasExceededDataLimit = function (assessment) {
        return assessment.dataRowCount > $scope.results.dataRowsProcessLimit; // -1 for removing the table header
    }

    $scope.getRegulationSortedText = function (assessment) {
        if (assessment.regulations.length == 0) {
            return '';
        }
        var text = "";
        for (var i in assessment.regulations) {
            text += (assessment.regulations[i] + " ; ");
        }
        return text;
    }

    $scope.customFilter = function (assessment) {
        switch ($scope.sortType) {
            case 'severityText':
                return $scope.getSeverityWeight(assessment);
            case 'test':
                return assessment.test;
            case 'category':
                return assessment.category;
            case 'regulation':
                return $scope.getRegulationSortedText(assessment);
            default:
                console.log("Unknown filter", $scope.sortType);
                return 0;
        }
    }

    $scope.getSeverityWeight = function (assessment) {
        try {
            return $scope.SEVERITIES[assessment.severityText].weight;
        } catch (err) {
            return 0;
        }
    }

    $scope.getCursor = function (assessment) {
        return $scope.hasExtraDetails(assessment) ? { 'cursor': 'pointer' } : { 'cursor': 'not-allowed' };
    }

    $scope.htmlTextToLines = function (text) {
        var linesArr = [];
        var lines = text.split("<br>");
        for (var i = 0; i < lines.length; i++) {
            if (lines[i] == "<br>" && i == lines.length - 1) {
                //if last line is "<br>"
                break;
            }
            linesArr.push(lines[i]);
        }
        return linesArr;
    }

    $scope.normalizeText = function (assessment) {
        assessment.detailsFixed = $scope.htmlTextToLines(assessment.details);
        assessment.descriptionFixed = $scope.htmlTextToLines(assessment.description);
        assessment.remediationFixed = $scope.htmlTextToLines(assessment.remediation);
    }

    $scope.trimText = function (text, length) {
        if (text.length <= length) {
            return text;
        }
        return text.substr(0, length) + " ... (expand for full remidiation)";
    }
    
    $scope.formatDataCountForTableIcon = function (assessment) {
        if (assessment.dataRowCount > $scope.results.dataRowsCountLimit) {
            return $scope.GetNumberInThousands($scope.results.dataRowsCountLimit) + '+';
        }
        return $scope.GetNumberInThousands(assessment.dataRowCount);
    }

    $scope.formatDataCountForExceeded = function (assessment) {
        if (assessment.dataRowCount > $scope.results.dataRowsCountLimit) {
            return "over " + $scope.GetNumberInThousands($scope.results.dataRowsCountLimit);
        }
        return $scope.GetNumberInThousands(assessment.dataRowCount);
    }
    
    $scope.fixedNumberDataResults = function (assessment) {
        return assessment.data.length > 0 ? assessment.data.length - 1 : 0; // Not counting the header row
    }

    $scope.getDataTooltip = function (assessment) {
        var numberOfResults = $scope.fixedNumberDataResults(assessment);
        if ($scope.hasExceededDataLimit(assessment)) {
            return "Only " + $scope.GetNumberInThousands(numberOfResults) + " results inside. Expand for full details"
        }
        return $scope.GetNumberInThousands(numberOfResults) + " result" + (numberOfResults == 1 ? '' : 's') + " inside";
    }

    $scope.getRemediationTooltip = function (assessment) {
        if (assessment.remediation.length == 0) {
            // No remediation
            return "";
        }

        if (assessment.remediationFixed.length > 1) {
            // Normalization was taken
            return "Expand for remediation";
        }

        if (assessment.remediation.length > $scope.MAX_REMEDIATION_TOOLTIP_LENGTH) {
            // Too long remediation
            return $scope.trimText(assessment.remediation, $scope.MAX_REMEDIATION_TOOLTIP_LENGTH);
        }

        return assessment.remediation;
    }

    $scope.normalizeScore = function (assessment) {
        var num = parseFloat(assessment.score);
        if (num == null || isNaN(num)) {
            //console.log("Failed parsing assessment score", assessment);
            assessment.score = $scope.INVALID_ASSESSMENT_SCORE;
            return;
        }

        if (num > 10 || num <= 0) {
            //console.log("Found invalid assessment score", assessment);
            assessment.score = $scope.INVALID_ASSESSMENT_SCORE;
            return;
        }

        assessment.score = $scope.getScoreFormatting(assessment.score);
    }

    $scope.setDoughnut = function () {
        var options = {
            legend: false,
            responsive: false
        };

        var labelsArray = [];
        var percentageArray = [];
        var backgroundArray = [];
        var backgroundHoverArray = [];
        for (var status in $scope.STATUSES) {
            labelsArray.push(status);
            percentageArray.push($scope.STATUSES[status].counter);
            backgroundArray.push($scope.STATUSES[status].doughnutBackground);
            backgroundHoverArray.push($scope.STATUSES[status].doughnutBackgroundHover);
        }

        new Chart(document.getElementById("canvas1"), {
            type: 'doughnut',
            tooltipFillColor: "rgba(51, 51, 51, 0.55)",
            data: {
                labels: labelsArray,
                datasets: [{
                    data: percentageArray,
                    backgroundColor: backgroundArray,
                    hoverBackgroundColor: backgroundHoverArray
                }]
            },
            options: options
        });
    }

    $scope.setPagesView = function () {
        if ($scope.numberOfAllTestsToShowInTable <= $scope.MAX_EVENTS_IN_PAGE) {
            $scope.maxPages = 1;
        } else {
            $scope.maxPages = Math.floor($scope.numberOfAllTestsToShowInTable / $scope.MAX_EVENTS_IN_PAGE);
            if ($scope.numberOfAllTestsToShowInTable % $scope.MAX_EVENTS_IN_PAGE > 0) {
                $scope.maxPages++;
            }
        }
        $scope.setPage(1);
    }

    $scope.setPage = function (value) {
        if (value > 0 && value <= $scope.maxPages) {
            $scope.activePage.value = value;
            $scope.SetTablePaging();
            $scope.setEventsSummaryText();
        }
    }

    $scope.showTestInTable = function (assessment) {
        return assessment.result != 'Error';
    }

    $scope.showScanResult = function (result) {
        return $scope.showErrorsSummary || result != 'Error';
    }

    $scope.SetTablePaging = function () {
        $scope.fromIndex = $scope.GetFirstFilteredIndex();
        $scope.toIndex = $scope.GetLastFilteredIndex();
    }

    $scope.GetFirstFilteredIndex = function () {
        return $scope.numberOfAllTestsToShowInTable == 0 ? 0 : ($scope.activePage.value - 1) * $scope.MAX_EVENTS_IN_PAGE;
    }

    $scope.GetLastFilteredIndex = function () {
        return Math.min($scope.fromIndex + $scope.MAX_EVENTS_IN_PAGE, $scope.numberOfAllTestsToShowInTable);
    }

    $scope.getPagesNavigationText = function () {
        return $scope.GetNumberInThousands($scope.activePage.value) + " / " + $scope.GetNumberInThousands($scope.maxPages);
    }

    $scope.setEventsSummaryText = function () {
        $scope.summaryText =
            "Showing " + $scope.GetNumberInThousands($scope.numberOfAllTestsToShowInTable == 0 ? 0 : $scope.fromIndex + 1) +
            " to " + $scope.GetNumberInThousands($scope.numberOfAllTestsToShowInTable == 0 ? 0 : $scope.toIndex) +
            " out of " + $scope.GetNumberInThousands($scope.numberOfAllTestsToShowInTable) +
            " assessments";
    }

    $scope.getEnableDisableStyle = function(condition) {
        return condition ? {} : { 'cursor': 'not-allowed', 'color': 'rgb(241, 173, 122)' };
    }

    $scope.getPreviousPageButtonStyle = function () {
        return $scope.getEnableDisableStyle($scope.activePage.value > 1);
    }

    $scope.getNextPageButtonStyle = function () {
        return $scope.getEnableDisableStyle($scope.activePage.value < $scope.maxPages);
    }

    $scope.getImpervaUrl = function () {
        return $scope.appendUtmCode("https://www.imperva.com");
    }

    $scope.getSecureSphereUrl = function () {
        return $scope.appendUtmCode("https://www.imperva.com/Products/DatabaseAssessment");
    }

    $scope.getOnlineFormUrl = function () {
        return $scope.appendUtmCode("https://www.imperva.com/Resources/MoreInfo");
    }

    $scope.appendUtmCode = function (url) {
        return url + $scope.results.utm;
    }

    $scope.hasErrors = function (result) {
        return $scope.results.hasPermissionsErrors;
    }

    $scope.resultsToString = function () {
        return  "scuba_version={" + $scope.results['version'] + "}&" +
                "scuba_platform={" + $scope.results['platform'] + "}&" +
                "scuba_database={" + $scope.results['database'] + "}&" +
                "scuba_vulnerabilities_total={" + $scope.vulnerabilitiesTests + "}&" +
                "scuba_vulnerabilities_fail={" + $scope.vulnerabilitiesFailures + "}&" +
                "scuba_complianceReadiness={" + $scope.complianceReadiness + "}&" +
                "scuba_cis_total={" + $scope.REGULATIONS['CIS'].count + "}&" +
                "scuba_cis_fail={" + $scope.REGULATIONS['CIS'].failures + "}&" +
                "scuba_disa_total={" + $scope.REGULATIONS['DISA (STIG)'].count + "}&" +
                "scuba_disa_fail={" + $scope.REGULATIONS['DISA (STIG)'].failures + "}&" +
                "scuba_tests_all={" + $scope.results['assessments'].length + "}&" +
                "scuba_tests_fail={" + $scope.STATUSES['Failed'].counter + "}&" +
                "scuba_tests_pass={" + $scope.STATUSES['Passed'].counter + "}&" +
                "scuba_tests_info={" + $scope.STATUSES['Info'].counter + "}&" +
                "scuba_tests_error={" + $scope.STATUSES['Error'].counter + "}&" +
                "scuba_tests_sev_critical={" + $scope.SEVERITIES['Critical'].failures + "}&" +
                "scuba_tests_sev_high={" + $scope.SEVERITIES['High'].failures + "}&" +
                "scuba_tests_sev_medium={" + $scope.SEVERITIES['Medium'].failures + "}&" +
                "scuba_tests_sev_low={" + $scope.SEVERITIES['Low'].failures + "}&" +
                "scuba_total_time={" + $scope.results['scanTimeMinutes'] + "}&" +
                "scuba_databaseVersion={" + $scope.results['databaseVersion'] + "}&" +
                "scuba_osVersion={" + $scope.results['osVersion'] + "}";
    }

    $scope.encodeString = function (str) {
        try {
            //return btoa(str);
            return base32.encode(str);
        } catch (err) {
            console.log("Unable to base32 encode", err);
            // Use plain-text if encoding failed
            return str;
        }
    }

    $scope.setStatsUrl = function () {
        var fullUrl = $scope.GA_DefaultLink + "?scuba_stats={" + $scope.encodeString($scope.resultsToString()) + "}";
        $scope.GA_Address = $sce.trustAsResourceUrl(fullUrl);
    }

    $scope.setGAIframeLazyLoading = function () {
        /*
            Using lazy loading 'cause loading an iframe delays total page loading time.
            Since this iframe is not visible, there is no issue with lazy loading
            Adding an additional 2-second delay (after DOM has completed loading) because of donught chart total animation time
        */
        angular.element(document).ready(function () {
            $timeout(function () {
                $scope.setStatsUrl();
                $scope.$apply();
            }, 2000);
        });
    }

    $scope.main = function () {
        $scope.setAssessmentResults();
        $scope.updateStatistics();
        $scope.setGauge();
        $scope.setDoughnut();
        $scope.setPagesView();
        $scope.setGAIframeLazyLoading();

        console.log("App loaded");
    }

    /*********************** MAIN *****************************/
    $scope.main();
});