<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Test for Grandfathering</title>
    <script src="/js-test-resources/js-test.js"></script>
    <script src="resources/util.js"></script>
</head>
<body>
<script>
    const firstPartyOrigin = "http://localhost:8000";
    const firstPartyBaseUrl = firstPartyOrigin + "/resourceLoadStatistics/resources";
    const firstPartyCookieName = "firstPartyCookie";
    const thirdPartyCookieName = "thirdPartyCookie";
    const cookieValue = "value";
    const subPathToSetFirstPartyCookie = "/set-cookie.py?name=" + firstPartyCookieName + "&value=" + cookieValue;
    const returnUrl = firstPartyOrigin + "/resourceLoadStatistics/grandfathering.html";
    const thirdPartyOrigin = "http://127.0.0.1:8000";
    const thirdPartyBaseUrl = thirdPartyOrigin + "/resourceLoadStatistics/resources";
    const subPathToSetThirdPartyCookie = "/set-cookie.py?name=" + thirdPartyCookieName + "&value=" + cookieValue;

    function finishTest() {
        setEnableFeature(false, function() {
            testRunner.notifyDone();
        });
    }

    function fireDataModificationHandlerAndContinue() {
        testRunner.installStatisticsDidScanDataRecordsCallback(function() {
            runTest();
        });
        testRunner.statisticsProcessStatisticsAndDataRecords();
    }

    function clearInMemoryAndPersistentStoreAndContinue() {
        testRunner.statisticsClearInMemoryAndPersistentStore(function() {
            runTest();
        });
    }

    function runTest() {
        switch (document.location.hash) {
            case "#step1":
                // Set a first-party cookie for localhost.
                document.location.href = firstPartyBaseUrl + subPathToSetFirstPartyCookie + "#" + returnUrl + "#step2";
                break;
            case "#step2":
                document.location.hash = "step3";
                // Check that localhost's cookie is there.
                if (document.cookie !== firstPartyCookieName + "=" + cookieValue)
                    testFailed("First-party cookie not set.");
                runTest();
                break;
            case "#step3":
                document.location.hash = "step4";
                // Clear store to trigger grandfathering.
                clearInMemoryAndPersistentStoreAndContinue();
                break;
            case "#step4":
                document.location.hash = "step5";
                // Set localhost as prevalent resource.
                testRunner.setStatisticsPrevalentResource("http://localhost", true, function() {
                    if (!testRunner.isStatisticsPrevalentResource("http://localhost"))
                        testFailed("Localhost did not get set as prevalent resource.");
                    runTest();
                });
                break;
            case "#step5":
                // Set a first-party cookie for 127.0.0.1.
                document.location.href = thirdPartyBaseUrl + subPathToSetThirdPartyCookie + "#" + returnUrl + "#step6";
                break;
            case "#step6":
                document.location.hash = "step7";
                // Set 127.0.0.1 as prevalent resource
                testRunner.setStatisticsPrevalentResource("http://127.0.0.1", true, function() {
                    if (!testRunner.isStatisticsPrevalentResource("http://127.0.0.1"))
                        testFailed("127.0.0.1 did not get set as prevalent resource.");
                    runTest();
                });
                break;
            case "#step7":
                document.location.hash = "step8";
                // Trigger a purge.
                fireDataModificationHandlerAndContinue();
                break;
            case "#step8":
                // Check that localhost's cookie is still there.
                if (document.cookie !== firstPartyCookieName + "=" + cookieValue)
                    testFailed("First-party cookie purged.");
                else
                    testPassed("Grandfathered cookie was not purged.");
                finishTest();
                break;
            default:
                testFailed("Should not be reached.");
                finishTest();
        }
    }

    if (document.location.hash === "" && window.testRunner && window.internals) {
        testRunner.waitUntilDone();
        setEnableFeature(true, function() {
            testRunner.setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(false);
            testRunner.setStatisticsMinimumTimeBetweenDataRecordsRemoval(0);

            testRunner.dumpChildFramesAsText();
            document.location.hash = "step1";
            runTest();
        });
    } else
        runTest();
</script>
</body>
</html>
