<!--
 Copyright (C) 2019-2022 Apple Inc. All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />

    <title>JetStream Next</title>

    <link rel="stylesheet" href="resources/JetStream.css">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, viewport-fit=cover">

    <script>
    const isInBrowser = true;
    const isD8 = false;
    const isSpiderMonkey = false;
    if (globalThis?.location?.search) {
        globalThis.JetStreamParamsSource = new URLSearchParams(globalThis?.location?.search);
    }
    globalThis.allIsGood = true;
    window.onerror = function(e) {
        if (e == "Script error.") {
            // This is a workaround for Firefox on iOS which has an uncaught exception from
            // its injected script. We should not stop the benchmark from running due to that
            // if it can otherwise run.
            return;
        }
        globalThis.allIsGood = false;
    }

    async function initialize() {
        if (!JetStreamParams.isDefault) {
            showNonDefaultParams();
        }
        if (globalThis.allIsGood) {
            try {
                await JetStream.initialize();
            } catch (e) {
                globalThis.allIsGood = false;
                console.error(e);
            }
        }
        if (!globalThis.allIsGood) {
            let statusElement = document.getElementById("status");
            statusElement.classList.remove('loading');
            statusElement.classList.add('error');
            statusElement.innerHTML = "<h2>ERROR</h2><p>Errors were encountered during page load. Refusing to run a partial benchmark suite.</p>";
        }
    }
    
    function showNonDefaultParams() {
        document.body.classList.add("nonDefaultParams"); 
        const body = document.querySelector("#non-standard-params-table tbody");
        const nonDefaultParams = JetStreamParams.nonDefaultParams;
        console.warn(`Using non standard params: ${JSON.stringify(nonDefaultParams, null, 2)}`)
        for (const [key, value] of  Object.entries(nonDefaultParams)) {
            const defaultValue = DefaultJetStreamParams[key]
            const row = body.insertRow();
            row.insertCell().textContent = key;
            row.insertCell().textContent = JSON.stringify(value);
            row.insertCell().textContent = JSON.stringify(defaultValue);
        }
    }
    </script>

    <script src="utils/params.js"></script>
    <script src="JetStreamDriver.js"></script>

</head>
<body onload="initialize()">
<h1 class="logo">
    <div id="jetstreams">
        <a href="index.html" class="logo-image">JetStream Next</a>
    </div>
</h1>

<main>
    <p class="summary">JetStream Next is a JavaScript and WebAssembly benchmark suite focused on the most advanced web applications. It rewards browsers that start up quickly, execute code quickly, and run smoothly. For more information, read the <a href="in-depth.html">in-depth analysis</a>. Bigger scores are better.</p>
    <div id="non-default-params">
        <h2>Non-standard Parameters</h2>
        <p>
            JetStream ran with non-standard parameters.<br />
            The results are likely not comparable to default runs.
        </p>
        <table id="non-standard-params-table">
            <thead>
                <tr>
                    <th>Param</th>
                    <th>Value</th>
                    <th>Default</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>
    </div>
    <p class="summary" id="mode-description"></p>

    <div id="result-summary"></div>
    <div id="status" class="loading">
        <div id="status-text">Loading Benchmark...</div>
        <div id="status-progress-container">
            <div id="status-progress-bar" style="width: 0%"></div>
        </div>
    </div>

    <div id="results"></div>
</main>
<iframe id="magic"></iframe>
</body>
</html>
