<!DOCTYPE html>
<html>
<head>
    <script src="/js-test-resources/js-test.js"></script>
    <script src="/cookies/resources/cookie-utilities.js"></script>
    <script src="resources/util.js"></script>
</head>
<body onload="setTimeout('runTest()', 0)">
<script>
    description("Check that cookies created by JavaScript after a cross-site navigation with link query get capped to 24 hours.");
    jsTestIsAsync = true;

    function testCookies() {
        let passedTests = 0;
        function checkThatCookieDoesNotExpireAfter(cookieData, maxAgeInSeconds) {
            let now = new Date();
            let maxExpiryDateInMilliseconds = now.getTime() + (maxAgeInSeconds * 1000);

            if (maxExpiryDateInMilliseconds > cookieData["expires"])
                ++passedTests;
            else
                testFailed("Cookie named " + cookieData["name"] + " expires in more than " + maxAgeInSeconds + " seconds.");
        }

        const twelveHoursInSeconds = 12 * 60 * 60;
        const shortLivedCookieMaxAge = { name : "shortLivedCookieMaxAge", lifetime : "Max-Age=" + twelveHoursInSeconds + ";" };
        document.cookie = shortLivedCookieMaxAge.name + "=foobar; " + shortLivedCookieMaxAge.lifetime + " path=/";

        const twelveHoursAsExpiresDate = createExpiresDateFromMaxAge(twelveHoursInSeconds);
        const shortLivedCookieExpires = { name : "shortLivedCookieExpires", lifetime : "Expires=" + twelveHoursAsExpiresDate + ";" };
        document.cookie = shortLivedCookieExpires.name + "=foobar; " + shortLivedCookieExpires.lifetime + " path=/";

        const oneDayInSeconds = 2 * twelveHoursInSeconds;
        const twoDaysInSeconds = 2 * oneDayInSeconds;
        const longLivedCookieMaxAge = { name : "longLivedCookieMaxAge", lifetime : "Max-Age=" + twoDaysInSeconds + ";" };
        document.cookie = longLivedCookieMaxAge.name + "=foobar; " + longLivedCookieMaxAge.lifetime + " path=/";

        const twoDaysAsExpiresDate = createExpiresDateFromMaxAge(twoDaysInSeconds);
        const longLivedCookieExpires = { name : "longLivedCookieExpires", lifetime : "Expires=" + twoDaysAsExpiresDate + ";" };
        document.cookie = longLivedCookieExpires.name + "=foobar; " + longLivedCookieExpires.lifetime + " path=/";

        const overTwelveHoursInSeconds = twelveHoursInSeconds + 30;
        const overOneDayInSeconds = oneDayInSeconds + 30;
        if (internals) {
            let cookies = internals.getCookies();
            if (!cookies.length)
                testFailed("No cookies found.");
            for (let cookie of cookies) {
                switch (cookie.name) {
                    case shortLivedCookieMaxAge.name:
                        checkThatCookieDoesNotExpireAfter(cookie, overTwelveHoursInSeconds);
                        break;
                    case shortLivedCookieExpires.name:
                        checkThatCookieDoesNotExpireAfter(cookie, overTwelveHoursInSeconds);
                        break;
                    case longLivedCookieMaxAge.name:
                        checkThatCookieDoesNotExpireAfter(cookie, overOneDayInSeconds);
                        break;
                    case longLivedCookieExpires.name:
                        checkThatCookieDoesNotExpireAfter(cookie, overOneDayInSeconds);
                        break;
                }
            }

            resetCookiesForCurrentOrigin();

            if (passedTests === 4) {
                testPassed("The two short-lived cookies don't expire after more than " + overTwelveHoursInSeconds + " seconds.");
                testPassed("The two long-lived cookies don't expire after more than " + overOneDayInSeconds + " seconds.");
            } else
                testFailed("At least one cookie's expiry attribute was beyond the test thresholds.");
        } else
            testFailed("No internals object.");
        
        setEnableFeature(false, finishJSTest);
    }

    function navigateCrossOrigin() {
        document.location.href = destinationOrigin + "/resourceLoadStatistics/capped-lifetime-for-cookie-set-in-js-with-link-query-from-prevalent-resource.html?link=query";
    }

    const destinationOrigin = "http://localhost:8000";
    const prevalentResourceOrigin = "http://127.0.0.1:8000";
    function runTest() {
        if (document.location.origin === prevalentResourceOrigin) {
            testRunner.setUseITPDatabase(true);
            setEnableFeature(true, function () {
                testRunner.setStatisticsPrevalentResource(prevalentResourceOrigin, true, function() {
                    if (!testRunner.isStatisticsPrevalentResource(prevalentResourceOrigin))
                        testFailed("Host did not get set as prevalent resource.");
                    testRunner.statisticsUpdateCookieBlocking(navigateCrossOrigin);
                });

            });
        } else {
            testCookies();
        }
    }
</script>
</body>
</html>
