<html>
<head>
    <script>
        const hashArguments = document.location.hash.substring(1).split(",");
        const userShouldGrantAccess = hashArguments[0] === "userShouldGrantAccess";
        const userShouldBeConsulted = hashArguments[1] === "userShouldBeConsulted";
        const policyShouldGrantAccess = hashArguments[2] === "policyShouldGrantAccess";
        const isSameOriginIframe = hashArguments[3] === "isSameOriginIframe";
        const originIsNull = hashArguments[4] === "originIsNull";

        var requestStorageAccessResolved;

        function messageToTop(messagePrefix, fetchData) {
            if (originIsNull) {
                top.postMessage(messagePrefix, "http://127.0.0.1:8000");
            } else {
                top.postMessage(messagePrefix + " document.cookie == " + document.cookie +
                    (fetchData ? ", cookies seen server-side == " + JSON.stringify(fetchData) : ""), "http://127.0.0.1:8000");
            }
        }

        window.addEventListener("message", receiveMessage, false);

        function receiveMessage(event) {
            if (event.origin === "http://127.0.0.1:8000") {
                if (event.data.indexOf("reportBackCookies") !== -1) {
                    fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
                        return response.json();
                    }).then(function(data) {
                        messageToTop("PASS.", data);
                    }).catch(function(error) {
                        console.log(error.message);
                    });
                } else {
                    messageToTop("FAIL Unknown request.");
                }
            } else {
                messageToTop("Fail Received a message from an unexpected origin: " + event.origin);
            }
        }

        function makeRequestWithUserGesture() {
            var promise = document.requestStorageAccess();
            promise.then(
                function () {
                    requestStorageAccessResolved = true;
                    continueAfterRequestWithUserGesture();
                },
                function () {
                    requestStorageAccessResolved = false;
                    continueAfterRequestWithUserGesture();
                }
            );
        }

        function continueAfterRequestWithUserGesture() {
            var promise = document.hasStorageAccess();
            promise.then(
                function (hasAccess) {
                    if (requestStorageAccessResolved
                        && hasAccess
                        && (userShouldGrantAccess || !userShouldBeConsulted)
                        && policyShouldGrantAccess) {
                        fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
                            return response.json();
                        }).then(function(data) {
                            messageToTop("PASS Storage access was granted.", data);
                        }).catch(function(error) {
                            console.log(error.message);
                        });

                    } else if (!hasAccess
                        && !requestStorageAccessResolved
                        && ((!userShouldGrantAccess && userShouldBeConsulted) || !policyShouldGrantAccess)) {
                        if (originIsNull) {
                            messageToTop("PASS Storage access was denied for origin null.");
                        } else {
                            fetch("echo-incoming-cookies-as-json.php", { credentials: "same-origin" }).then(function(response) {
                                return response.json();
                            }).then(function(data) {
                                messageToTop("PASS Storage access was denied.", data);
                            }).catch(function(error) {
                                console.log(error.message);
                            });
                        }
                    } else
                        messageToTop("FAIL Storage access was " +
                            (hasAccess ? "" : "not ") +
                            "granted and requestStorageAccessResolved was " +
                            (requestStorageAccessResolved ? "" : "not ") +
                            "granted but should " +
                            (userShouldGrantAccess && policyShouldGrantAccess ? "" : "not ") +
                            "have been granted.");
                },
                function (reason) {
                    messageToTop("FAIL document.hasStorageAccess() was rejected. Reason: " + reason);
                }
            );
        }
    </script>
</head>
<body onclick="makeRequestWithUserGesture()">
</body>
</html>