/*
 * Copyright (C) 2018 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.
 */

WI.AuditTestCase = class AuditTestCase extends WI.AuditTestBase
{
    constructor(name, test, options = {})
    {
        console.assert(typeof test === "string");

        super(name, options);

        this._test = test;
    }

    // Static

    static async fromPayload(payload)
    {
        if (typeof payload !== "object" || payload === null)
            return null;

        if (payload.type !== WI.AuditTestCase.TypeIdentifier)
            return null;

        if (typeof payload.name !== "string") {
            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("name")));
            return null;
        }

        if (typeof payload.test !== "string") {
            WI.AuditManager.synthesizeError(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("test")));
            return null;
        }

        let options = {};

        if (typeof payload.description === "string")
            options.description = payload.description;
        else if ("description" in payload)
            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("description")));

        if (typeof payload.supports === "number")
            options.supports = payload.supports;
        else if ("supports" in payload)
            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-number \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("supports")));

        if (typeof payload.setup === "string")
            options.setup = payload.setup;
        else if ("setup" in payload)
            WI.AuditManager.synthesizeWarning(WI.UIString("\u0022%s\u0022 has a non-string \u0022%s\u0022 value").format(payload.name, WI.unlocalizedString("setup")));

        if (typeof payload.disabled === "boolean")
            options.disabled = payload.disabled;

        return new WI.AuditTestCase(payload.name, payload.test, options);
    }

    // Public

    get test() { return this._test; }

    toJSON(key)
    {
        let json = super.toJSON(key);
        json.test = this._test;
        return json;
    }

    // Protected

    async run()
    {
        const levelStrings = Object.values(WI.AuditTestCaseResult.Level);
        let level = null;
        let data = {};
        let metadata = {
            url: WI.networkManager.mainFrame.url,
            startTimestamp: null,
            endTimestamp: null,
        };
        let resolvedDOMNodes = null;

        function setLevel(newLevel) {
            let newLevelIndex = levelStrings.indexOf(newLevel);
            if (newLevelIndex < 0) {
                addError(WI.UIString("Return string must be one of %s").format(JSON.stringify(levelStrings)));
                return;
            }

            if (newLevelIndex <= levelStrings.indexOf(level))
                return;

            level = newLevel;
        }

        function addError(value) {
            setLevel(WI.AuditTestCaseResult.Level.Error);

            if (!data.errors)
                data.errors = [];

            data.errors.push(value);
        }

        async function parseResponse(response) {
            let remoteObject = WI.RemoteObject.fromPayload(response.result, WI.mainTarget);
            if (response.wasThrown || (remoteObject.type === "object" && remoteObject.subtype === "error")) {
                addError(remoteObject.description);
                return;
            }

            if (remoteObject.type === "boolean") {
                setLevel(remoteObject.value ? WI.AuditTestCaseResult.Level.Pass : WI.AuditTestCaseResult.Level.Fail);
                return;
            }

            if (remoteObject.type === "string") {
                setLevel(remoteObject.value.trim().toLowerCase());
                return;
            }

            if (remoteObject.type !== "object" || remoteObject.subtype) {
                addError(WI.UIString("Return value is not an object, string, or boolean"));
                return;
            }

            const options = {
                ownProperties: true,
            };

            function checkResultProperty(key, value, type, subtype) {
                function addErrorForValueType(valueType) {
                    let errorString = null;
                    if (valueType === "object" || valueType === "array")
                        errorString = WI.UIString("\u0022%s\u0022 must be an %s");
                    else
                        errorString = WI.UIString("\u0022%s\u0022 must be a %s");
                    addError(errorString.format(key, valueType));
                }

                if (value.subtype !== subtype) {
                    addErrorForValueType(subtype);
                    return null;
                }

                if (value.type !== type) {
                    addErrorForValueType(type);
                    return null;
                }

                if (type === "boolean" || type === "string")
                    return value.value;

                return value;
            }

            async function resultArrayForEach(key, value, callback) {
                let array = checkResultProperty(key, value, "object", "array");
                if (!array)
                    return;

                let arrayProperties = await new Promise((resolve, reject) => array.getPropertyDescriptors(resolve, options));
                for (let i = 0; i < array.size; ++i) {
                    let arrayPropertyForIndex = arrayProperties.find((arrayProperty) => arrayProperty.name === String(i));
                    if (arrayPropertyForIndex)
                        await callback(arrayPropertyForIndex);
                }
            }

            let properties = await new Promise((resolve, reject) => remoteObject.getPropertyDescriptors(resolve, options));
            for (let property of properties) {
                let key = property.name;
                if (key === "__proto__")
                    continue;

                let value = property.value;

                switch (key) {
                case "level": {
                    let levelString = checkResultProperty(key, value, "string");
                    if (levelString)
                        setLevel(levelString.trim().toLowerCase());
                    break;
                }

                case "pass":
                    if (checkResultProperty(key, value, "boolean"))
                        setLevel(WI.AuditTestCaseResult.Level.Pass);
                    break;

                case "warn":
                    if (checkResultProperty(key, value, "boolean"))
                        setLevel(WI.AuditTestCaseResult.Level.Warn);
                    break;

                case "fail":
                    if (checkResultProperty(key, value, "boolean"))
                        setLevel(WI.AuditTestCaseResult.Level.Fail);
                    break;

                case "error":
                    if (checkResultProperty(key, value, "boolean"))
                        setLevel(WI.AuditTestCaseResult.Level.Error);
                    break;

                case "unsupported":
                    if (checkResultProperty(key, value, "boolean"))
                        setLevel(WI.AuditTestCaseResult.Level.Unsupported);
                    break;

                case "domNodes":
                    await resultArrayForEach(key, value, async (item) => {
                        if (!item || !item.value || item.value.type !== "object" || item.value.subtype !== "node") {
                            addError(WI.UIString("All items in \u0022%s\u0022 must be valid DOM nodes").format(WI.unlocalizedString("domNodes")));
                            return;
                        }

                        let domNodeId = await new Promise((resolve, reject) => item.value.pushNodeToFrontend(resolve));
                        let domNode = WI.domManager.nodeForId(domNodeId);
                        if (!domNode)
                            return;

                        if (!data.domNodes)
                            data.domNodes = [];
                        data.domNodes.push(WI.cssPath(domNode, {full: true}));

                        if (!resolvedDOMNodes)
                            resolvedDOMNodes = [];
                        resolvedDOMNodes.push(domNode);
                    });
                    break;

                case "domAttributes":
                    await resultArrayForEach(key, value, (item) => {
                        if (!item || !item.value || item.value.type !== "string" || !item.value.value.length) {
                            addError(WI.UIString("All items in \u0022%s\u0022 must be non-empty strings").format(WI.unlocalizedString("domAttributes")));
                            return;
                        }

                        if (!data.domAttributes)
                            data.domAttributes = [];
                        data.domAttributes.push(item.value.value);
                    });
                    break;

                case "errors":
                    await resultArrayForEach(key, value, (item) => {
                        if (!item || !item.value || item.value.type !== "object" || item.value.subtype !== "error") {
                            addError(WI.UIString("All items in \u0022%s\u0022 must be error objects").format(WI.unlocalizedString("errors")));
                            return;
                        }

                        addError(item.value.description);
                    });
                    break;

                default:
                    if (value.objectId) {
                        try {
                            function inspectedPage_stringify() {
                                return JSON.stringify(this);
                            }
                            let stringifiedValue = await value.callFunction(inspectedPage_stringify);
                            data[key] = JSON.parse(stringifiedValue.value);
                        } catch {
                            addError(WI.UIString("\u0022%s\u0022 is not JSON serializable").format(key));
                        }
                    } else
                        data[key] = value.value;
                    break;
                }
            }
        }

        let target = WI.assumingMainTarget();

        let agentCommandFunction = null;
        let agentCommandArguments = {};
        if (target.hasDomain("Audit")) {
            agentCommandFunction = target.AuditAgent.run;
            agentCommandArguments.test = this._test;
        } else {
            agentCommandFunction = target.RuntimeAgent.evaluate;
            agentCommandArguments.expression = `(function() { "use strict"; return eval(\`(${this._test.replace(/`/g, "\\`")})\`)(); })()`;
            agentCommandArguments.objectGroup = WI.AuditTestCase.ObjectGroup;
            agentCommandArguments.doNotPauseOnExceptionsAndMuteConsole = true;
        }

        try {
            metadata.startTimestamp = new Date;
            let response = await agentCommandFunction.invoke(agentCommandArguments);
            metadata.endTimestamp = new Date;

            if (response.result.type === "object" && response.result.className === "Promise") {
                if (WI.RuntimeManager.supportsAwaitPromise()) {
                    metadata.asyncTimestamp = metadata.endTimestamp;
                    response = await target.RuntimeAgent.awaitPromise(response.result.objectId);
                    metadata.endTimestamp = new Date;
                } else {
                    response = null;
                    addError(WI.UIString("Async audits are not supported."));
                    setLevel(WI.AuditTestCaseResult.Level.Unsupported);
                }
            }

            if (response)
                await parseResponse(response);
        } catch (error) {
            metadata.endTimestamp = new Date;
            addError(error.message);
        }

        if (!level)
            addError(WI.UIString("Missing result level"));

        let options = {
            description: this.description,
            metadata,
        };
        if (!isEmptyObject(data))
            options.data = data;
        if (resolvedDOMNodes)
            options.resolvedDOMNodes = resolvedDOMNodes;
        this._result = new WI.AuditTestCaseResult(this.name, level, options);

        this.dispatchEventToListeners(WI.AuditTestBase.Event.ResultChanged);
    }
};

WI.AuditTestCase.TypeIdentifier = "test-case";
