<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>
let worker1 = new Worker("resources/worker-1.js");
let worker2 = new Worker("resources/worker-2.js");
let worker3 = null;

function createWorker3() {
    worker3 = new Worker("resources/worker-3.js");
}

function terminateWorker2FromPage() {
    worker2.terminate();
}

function terminateWorker3FromWorker() {
    worker3.postMessage("close");
}

function terminateWorker1ViaCollection() {
    worker1 = null;
}

function test()
{
    let workers = [];

    function addWorker(workerId, url) {
        workers.push({workerId, url});
        workers.sort((a, b) => a.url.localeCompare(b.url));
    }

    function removeWorker(workerId) {
        workers = workers.filter((x) => x.workerId !== workerId);
    }

    function dumpWorkers() {
        for (let {workerId, url} of workers)
            ProtocolTest.log("Worker - " + sanitizeURL(url));
        if (!workers.length)
            ProtocolTest.log("No Workers");
    }

    async function checkInternalProperties(expression, {terminated} = {}) {
        let evaluateResult = await InspectorProtocol.awaitCommand({
            method: "Runtime.evaluate",
            params: {
                expression,
                objectGroup: "test",
            },
        });

        ProtocolTest.assert(evaluateResult.result.type === "object", `Evaluate result of '${expression}' should have type 'object'.`);
        ProtocolTest.assert(evaluateResult.result.className === "Worker", `Evaluate result of '${expression}' should have className 'Worker'.`);

        let getPropertiesResult = await InspectorProtocol.awaitCommand({
            method: "Runtime.getProperties",
            params: {
                objectId: evaluateResult.result.objectId,
            },
        });

        let internalProperties = getPropertiesResult.internalProperties;
        ProtocolTest.assert(internalProperties.length === 1, `Worker '${expression}' should only have one internal property.`);

        ProtocolTest.assert(internalProperties[0].name === "terminated", `Worker '${expression}' should have 'terminated' internal property.`);
        ProtocolTest.assert(internalProperties[0].value.type === "boolean", `Internal 'terminated' property of '${expression}' should be a boolean.`);
        ProtocolTest.assert(internalProperties[0].value.value === terminated, `Internal 'terminated' property of '${expression}' should have value '${terminated}'.`);
    }


    let triggerNextCreate;
    let triggerNextTerminate;

    function waitForWorkerCreatedEvent(callback) {
        return new Promise((resolve, reject) => {
            triggerNextCreate = resolve;
        });
    }

    function waitForWorkerTerminatedEvent(callback) {
        return new Promise((resolve, reject) => {
            triggerNextTerminate = resolve;
        });
    }

    InspectorProtocol.eventHandler["Worker.workerCreated"] = (messageObject) => {
        addWorker(messageObject.params.workerId, messageObject.params.url);
        InspectorProtocol.sendCommand("Worker.initialized", {workerId: messageObject.params.workerId});
        if (triggerNextCreate)
            triggerNextCreate();
    };

    InspectorProtocol.eventHandler["Worker.workerTerminated"] = (messageObject) => {
        removeWorker(messageObject.params.workerId);
        if (triggerNextTerminate)
            triggerNextTerminate();
    };


    let suite = ProtocolTest.createAsyncSuite("Worker.CreateAndTerminate");

    suite.addTestCase({
        name: "Worker.enable",
        description: "Worker.enable informs the frontend of the two existing Workers",
        async test() {
            await InspectorProtocol.awaitCommand({method: "Worker.enable", params: {}});

            ProtocolTest.expectEqual(workers.length, 2, "Should be informed of two existing Workers.");
            dumpWorkers();

            await Promise.all([
                checkInternalProperties(`worker1`, {terminated: false}),
                checkInternalProperties(`worker2`, {terminated: false}),
            ]);
        }
    });

    suite.addTestCase({
        name: "Worker.workerCreated",
        description: "Should receive a Worker.workerCreated event when creating a Worker.",
        async test() {
            await Promise.all([
                waitForWorkerCreatedEvent(),
                ProtocolTest.evaluateInPage("createWorker3()"),
            ]);

            ProtocolTest.pass("Worker.workerCreated");
            dumpWorkers();

            await Promise.all([
                checkInternalProperties(`worker1`, {terminated: false}),
                checkInternalProperties(`worker2`, {terminated: false}),
                checkInternalProperties(`worker3`, {terminated: false}),
            ]);
        }
    });

    suite.addTestCase({
        name: "Worker.workerTerminated.Page",
        description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Page.",
        async test() {
            await Promise.all([
                waitForWorkerTerminatedEvent(),
                ProtocolTest.evaluateInPage("terminateWorker2FromPage()"),
            ]);

            ProtocolTest.pass("Worker.workerTerminated");
            dumpWorkers();

            await Promise.all([
                checkInternalProperties(`worker1`, {terminated: false}),
                checkInternalProperties(`worker2`, {terminated: true}),
                checkInternalProperties(`worker3`, {terminated: false}),
            ]);
        }
    });

    suite.addTestCase({
        name: "Worker.workerTerminated.Worker",
        description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Worker.",
        async test() {
            await Promise.all([
                waitForWorkerTerminatedEvent(),
                ProtocolTest.evaluateInPage("terminateWorker3FromWorker()"),
            ]);

            ProtocolTest.pass("Worker.workerTerminated");
            dumpWorkers();

            await Promise.all([
                checkInternalProperties(`worker1`, {terminated: false}),
                checkInternalProperties(`worker2`, {terminated: true}),
            ]);
        }
    });

    suite.addTestCase({
        name: "Worker.workerTerminated.GC",
        description: "Should receive a Worker.workerTerminated event when terminating a Worker via Garbage Collection.",
        async test() {
            let workerTerminatedPromise = waitForWorkerTerminatedEvent();
            await ProtocolTest.evaluateInPage("terminateWorker1ViaCollection()");
            await InspectorProtocol.awaitCommand({method: "Runtime.releaseObjectGroup", params: {objectGroup: "test"}});
            await InspectorProtocol.awaitCommand({method: "Heap.gc", params: {}});
            await workerTerminatedPromise;

            ProtocolTest.pass("Worker.workerTerminated");
            dumpWorkers();

            await checkInternalProperties(`worker2`, {terminated: true});
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for Worker.workerCreated and Worker.workerTerminated events.</p>
</body>
</html>
