<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test for Resource Load Statistics Pruning</title>
    <script src="/js-test-resources/js-test.js"></script>
</head>
<body>
<script>
    description("Tests that statistics are pruned in the right order.");
    jsTestIsAsync = true;

    const olderTimestamp = Math.round((new Date()).getTime() / 1000);
    const newerTimestamp = olderTimestamp + 10;
    const newestTimestamp = newerTimestamp + 10;

    const urlsToBePruned = [
        { url: "http://127.0.0.1:8000/temp", prevalent: false },
        { url: "http://127.0.0.2:8000/temp", prevalent: false },
        { url: "http://127.0.0.3:8000/temp", prevalent: true },
        { url: "http://127.0.0.4:8000/temp", prevalent: true },
        { url: "http://127.0.0.5:8000/temp", prevalent: false },
        { url: "http://127.0.0.6:8000/temp", prevalent: false },
        { url: "http://127.0.0.7:8000/temp", prevalent: true },
        { url: "http://127.0.0.8:8000/temp", prevalent: true }
    ];

    function checkIfPrevalentAccordingToInitialExpectation(begin, end) {
        var failed = false;
        for (var i = begin; i < end; ++i) {
            if (testRunner.isStatisticsPrevalentResource(urlsToBePruned[i].url) !== urlsToBePruned[i].prevalent) {
                testFailed("checkIfPrevalentAccordingToInitialExpectation: Test iteration " + currentTest + " failed. " + urlsToBePruned[i].url + (urlsToBePruned[i].prevalent ? " wasn't " : " was ") + "prevalent");
                failed = true;
            }
        }
        if (failed) {
            testRunner.statisticsResetToConsistentState(function() {
                finishJSTest();
            });
        }
    }

    function checkIfPrevalent(begin, end, expected) {
        var failed = false;
        for (var i = begin; i < end; ++i) {
            if (testRunner.isStatisticsPrevalentResource(urlsToBePruned[i].url) !== expected) {
                testFailed("checkIfPrevalent: Test iteration " + currentTest + " failed. " + urlsToBePruned[i].url + (expected ? " wasn't " : " was ") + "prevalent");
                failed = true;
            }
        }
        if (failed) {
            testRunner.statisticsResetToConsistentState(function() {
                finishJSTest();
            });
        }
    }

    function initializeStatisticsAndRunTests(step) {
        switch (step) {
            // Non-prevalent without user interaction to be pruned first.
            case 1:
                testRunner.setStatisticsLastSeen(urlsToBePruned[0].url, olderTimestamp, function() { initializeStatisticsAndRunTests(2); });
                break;
            case 2:
                testRunner.setStatisticsLastSeen(urlsToBePruned[1].url, newerTimestamp, function() { initializeStatisticsAndRunTests(3); });
                break;
            // Prevalent without user interaction to be pruned second.
            case 3:
                testRunner.setStatisticsPrevalentResource(urlsToBePruned[2].url, true, function() { initializeStatisticsAndRunTests(4); });
                break;
            case 4:
                testRunner.setStatisticsLastSeen(urlsToBePruned[2].url, olderTimestamp, function() { initializeStatisticsAndRunTests(5); });
                break;
            case 5:
                testRunner.setStatisticsPrevalentResource(urlsToBePruned[3].url, true, function() { initializeStatisticsAndRunTests(6); });
                break;
            case 6:
                testRunner.setStatisticsLastSeen(urlsToBePruned[3].url, newerTimestamp, function() { initializeStatisticsAndRunTests(7); });
                break;
            // Non-prevalent with user interaction to be pruned third.
            case 7:
                testRunner.setStatisticsHasHadUserInteraction(urlsToBePruned[4].url, true, function() { initializeStatisticsAndRunTests(8); });
                break;
            case 8:
                testRunner.setStatisticsLastSeen(urlsToBePruned[4].url, olderTimestamp, function() { initializeStatisticsAndRunTests(9); });
                break;
            case 9:
                testRunner.setStatisticsHasHadUserInteraction(urlsToBePruned[5].url, true, function() { initializeStatisticsAndRunTests(10); });
                break;
            case 10:
                testRunner.setStatisticsLastSeen(urlsToBePruned[5].url, newerTimestamp, function() { initializeStatisticsAndRunTests(11); });
                break;
            // Prevalent with user interaction to be pruned last.
            case 11:
                testRunner.setStatisticsPrevalentResource(urlsToBePruned[6].url, true, function() { initializeStatisticsAndRunTests(12); });
                break;
            case 12:
                testRunner.setStatisticsHasHadUserInteraction(urlsToBePruned[6].url, true, function() { initializeStatisticsAndRunTests(13); });
                break;
            case 13:
                testRunner.setStatisticsLastSeen(urlsToBePruned[6].url, olderTimestamp, function() { initializeStatisticsAndRunTests(14); });
                break;
            case 14:
                testRunner.setStatisticsPrevalentResource(urlsToBePruned[7].url, true, function() { initializeStatisticsAndRunTests(15); });
                break;
            case 15:
                testRunner.setStatisticsHasHadUserInteraction(urlsToBePruned[7].url, true, function() { initializeStatisticsAndRunTests(16); });
                break;
            case 16:
                testRunner.setStatisticsLastSeen(urlsToBePruned[7].url, newerTimestamp, function() { initializeStatisticsAndRunTests(17); });
                break;
            case 17:
                checkIfPrevalentAccordingToInitialExpectation(0, urlsToBePruned.length);
                runTest();
                break;
        }
    }

    var currentTest;
    function checkStatisticsAfterPruning() {
        // Pruned entries should not be prevalent.
        checkIfPrevalent(0, currentTest, false);
        // Non-pruned entries should keep their expected status.
        checkIfPrevalentAccordingToInitialExpectation(currentTest, urlsToBePruned.length);
        testPassed("Test iteration " + currentTest + " passed.");
        if (currentTest < urlsToBePruned.length) {
            ++currentTest;
            testRunner.installStatisticsDidScanDataRecordsCallback(checkStatisticsAfterPruning);
            initializeStatisticsAndRunTests(1);
        } else {
            testRunner.statisticsResetToConsistentState(function() {
                finishJSTest();
            });
        }
    }

    let fillerUrl;
    function runTest() {
        fillerUrl = "http://127.0." + currentTest + ".1:8000/temp";
        testRunner.setStatisticsPrevalentResource(fillerUrl, true, function() {
            testRunner.setStatisticsHasHadUserInteraction(fillerUrl, true, function() {
                testRunner.setStatisticsLastSeen(fillerUrl, newestTimestamp, function() {
                    testRunner.statisticsProcessStatisticsAndDataRecords();
                });
            });
        });
    }

    if (window.testRunner) {
            testRunner.setUseITPDatabase(true);
        testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
        testRunner.setStatisticsMinimumTimeBetweenDataRecordsRemoval(0);
        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
        testRunner.setStatisticsMaxStatisticsEntries(urlsToBePruned.length);
        testRunner.setStatisticsPruneEntriesDownTo(urlsToBePruned.length);

        currentTest = 1;
        testRunner.installStatisticsDidScanDataRecordsCallback(checkStatisticsAfterPruning);
        initializeStatisticsAndRunTests(1);
    }
</script>
</body>
</html>
