TestPage.registerInitializer(() => {
    function log(object, indent) {
        for (let [name, value] of object) {
            if (typeof value === "string")
                value = sanitizeURL(value);
            else if (Array.isArray(value)) {
                if (value[0] instanceof DOMMatrix)
                    value[0] = [value[0].a, value[0].b, value[0].c, value[0].d, value[0].e, value[0].f];
                else if (value[0] instanceof Path2D)
                    value[0] = value[0].__data;
            }
            InspectorTest.log(indent + name + ": " + JSON.stringify(value));
        }
    }

    async function logRecording(recording, options = {}) {
        InspectorTest.log("initialState:");

        InspectorTest.log("  attributes:");
        log(Object.entries(recording.initialState.attributes), "    ");

        let currentState = recording.initialState.states.lastValue;
        if (currentState) {
            InspectorTest.log("  current state:");
            let state = await WI.RecordingState.swizzleInitialState(recording, currentState);
            log(state, "    ");
        }

        InspectorTest.log("  parameters:");
        log(Object.entries(recording.initialState.parameters), "    ");

        let currentContent = recording.initialState.content;
        if (currentContent)
            InspectorTest.log("  content: <filtered>");

        InspectorTest.log("frames:");
        for (let i = 0; i < recording.frames.length; ++i) {
            let frame = recording.frames[i];

            let frameText = `  ${i}:`;
            if (!isNaN(frame.duration))
                frameText += " (duration)";
            if (frame.incomplete)
                frameText += " (incomplete)";
            InspectorTest.log(frameText);

            for (let j = 0; j < frame.actions.length; ++j) {
                let action = frame.actions[j];
                let actionText = `    ${j}: ${action.name}`;

                let parameters = action.parameters.map((parameter) => {
                    if (typeof parameter === "object" && !Array.isArray(parameter))
                        return String(parameter);
                    return JSON.stringify(parameter);
                });
                if (action.isFunction)
                    actionText += "(" + parameters.join(", ") + ")";
                else if (!action.isGetter)
                    actionText += " = " + parameters[0];

                InspectorTest.log(actionText);

                if (action.swizzleTypes.length) {
                    let swizzleNames = action.swizzleTypes.map((item) => WI.Recording.displayNameForSwizzleType(item));
                    InspectorTest.log("      swizzleTypes: [" + swizzleNames.join(", ") + "]");
                }

                if (action.trace.length) {
                    InspectorTest.log("      trace:");

                    for (let k = 0; k < action.trace.length; ++k) {
                        let functionName = action.trace[k].functionName || "(anonymous function)";
                        InspectorTest.log(`        ${k}: ` + functionName);
                    }
                }

                if (action.snapshot) {
                    if (options.checkForContentChange)
                        InspectorTest.log(`      snapshot: <${currentContent === action.snapshot ? "FAIL" : "PASS"}: content changed>`);
                    else
                        InspectorTest.log("      snapshot: <filtered>");
                    currentContent = action.snapshot;
                }
            }
        }
    }

    window.getCanvas = function(type) {
        let canvases = WI.canvasManager.canvases.filter((canvas) => canvas.contextType === type);
        InspectorTest.assert(canvases.length === 1, `There should only be one canvas with type "${type}".`);
        if (canvases.length !== 1)
            return null;
        return canvases[0];
    };

    window.startRecording = function(type, resolve, reject, {frameCount, memoryLimit, checkForContentChange, callback} = {}) {
        let canvas = getCanvas(type);
        if (!canvas) {
            reject(`Missing canvas with type "${type}".`);
            return;
        }

        let swizzled = false;
        let lastFrame = false;

        InspectorTest.awaitEvent("LastFrame")
        .then((event) => {
            lastFrame = true;

            if (canvas.recordingActive) {
                if (!frameCount)
                    CanvasAgent.stopRecording(canvas.identifier).catch(reject);
            } else {
                InspectorTest.evaluateInPage(`cancelActions()`)
                .then(() => {
                    if (swizzled)
                        resolve();
                }, reject);
            }
        });

        let bufferUsed = 0;
        let recordingFrameCount = 0;
        function handleRecordingProgress(event) {
            InspectorTest.assert(canvas.recordingFrameCount > recordingFrameCount, "Additional frames were captured for this progress event.");
            recordingFrameCount = canvas.recordingFrameCount;

            InspectorTest.assert(canvas.recordingBufferUsed > bufferUsed, "Total memory usage increases with each progress event.");
            bufferUsed = canvas.recordingBufferUsed;
        }
        canvas.addEventListener(WI.Canvas.Event.RecordingProgress, handleRecordingProgress);

        canvas.awaitEvent(WI.Canvas.Event.RecordingStopped).then((event) => {
            canvas.removeEventListener(WI.Canvas.Event.RecordingProgress, handleRecordingProgress);

            let recording = event.data.recording;
            InspectorTest.assert(recording.source === canvas, "Recording should be of the given canvas.");
            InspectorTest.assert(recording.source.contextType === type, `Recording should be of a canvas with type "${type}".`);
            InspectorTest.assert(recording.source.recordingCollection.has(recording), "Recording should be in the canvas' list of recordings.");
            InspectorTest.assert(recording.frames.length === recordingFrameCount, `Recording should have ${recordingFrameCount} frames.`)

            if (frameCount)
                InspectorTest.assert(recording.frames.length === frameCount, `Recording frame count should match the provided value ${frameCount}.`)

            Promise.all(recording.actions.map((action) => action.swizzle(recording))).then(() => {
                swizzled = true;

                (callback ? callback(recording) : logRecording(recording, {checkForContentChange}))
                .then(() => {
                    if (lastFrame) {
                        InspectorTest.evaluateInPage(`cancelActions()`)
                        .then(resolve, reject);
                    }
                }, reject);
            });
        });

        canvas.awaitEvent(WI.Canvas.Event.RecordingStarted).then((event) => {
            InspectorTest.evaluateInPage(`performActions()`).catch(reject);
        });

        CanvasAgent.startRecording(canvas.identifier, frameCount, memoryLimit).catch(reject);
    };

    window.consoleRecord = function(type, resolve, reject) {
        let canvas = getCanvas(type);
        if (!canvas) {
            reject(`Missing canvas with type "${type}".`);
            return;
        }

        canvas.awaitEvent(WI.Canvas.Event.RecordingStopped).then((event) => {
            let recording = event.data.recording;

            InspectorTest.assert(recording.source === canvas, "Recording should be of the given canvas.");
            InspectorTest.assert(recording.source.contextType === type, `Recording should be of a canvas with type "${type}".`);
            InspectorTest.assert(recording.source.recordingCollection.has(recording), "Recording should be in the canvas' list of recordings.");

            InspectorTest.expectEqual(recording.displayName, "TEST", "The recording should have the name \"TEST\".");
            InspectorTest.expectEqual(recording.frames.length, 1, "The recording should have one frame.");
            InspectorTest.expectEqual(recording.frames[0].actions.length, 1, "The first frame should have one action.");
        }).then(resolve, reject);

        InspectorTest.evaluateInPage(`performConsoleActions()`);
    };
});
