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

TestHarness = class TestHarness extends WI.Object
{
    constructor()
    {
        super();

        this._logCount = 0;
        this._failureObjects = new Map;
        this._failureObjectIdentifier = 1;

        // Options that are set per-test for debugging purposes.
        this.forceDebugLogging = false;

        // Options that are set per-test to ensure deterministic output.
        this.suppressStackTraces = false;
    }

    completeTest()
    {
        throw new Error("Must be implemented by subclasses.");
    }

    addResult()
    {
        throw new Error("Must be implemented by subclasses.");
    }

    debugLog()
    {
        throw new Error("Must be implemented by subclasses.");
    }

    // If 'callback' is a function, it will be with the arguments
    // callback(error, result, wasThrown). Otherwise, a promise is
    // returned that resolves with 'result' or rejects with 'error'.

    // The options object accepts the following keys and values:
    // 'remoteObjectOnly': if true, do not unwrap the result payload to a
    // primitive value even if possible. Useful if testing WI.RemoteObject directly.
    evaluateInPage(string, callback, options={})
    {
        throw new Error("Must be implemented by subclasses.");
    }

    debug()
    {
        throw new Error("Must be implemented by subclasses.");
    }

    createAsyncSuite(name)
    {
        return new AsyncTestSuite(this, name);
    }

    createSyncSuite(name)
    {
        return new SyncTestSuite(this, name);
    }

    get logCount()
    {
        return this._logCount;
    }

    log(message)
    {
        ++this._logCount;

        if (this.forceDebugLogging)
            this.debugLog(message);
        else
            this.addResult(message);
    }

    newline()
    {
        this.log("");
    }

    json(object, filter)
    {
        this.log(JSON.stringify(object, filter || null, 2));
    }

    assert(condition, message)
    {
        if (condition)
            return;

        let stringifiedMessage = TestHarness.messageAsString(message);
        this.log("ASSERT: " + stringifiedMessage);
    }

    expectThat(actual, message)
    {
        this._expect(TestHarness.ExpectationType.True, !!actual, message, actual);
    }

    expectTrue(actual, message)
    {
        this._expect(TestHarness.ExpectationType.True, !!actual, message, actual);
    }

    expectFalse(actual, message)
    {
        this._expect(TestHarness.ExpectationType.False, !actual, message, actual);
    }

    expectNull(actual, message)
    {
        this._expect(TestHarness.ExpectationType.Null, actual === null, message, actual, null);
    }

    expectNotNull(actual, message)
    {
        this._expect(TestHarness.ExpectationType.NotNull, actual !== null, message, actual);
    }

    expectEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.Equal, expected === actual, message, actual, expected);
    }

    expectNotEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.NotEqual, expected !== actual, message, actual, expected);
    }

    expectShallowEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.ShallowEqual, Object.shallowEqual(actual, expected), message, actual, expected);
    }

    expectNotShallowEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.NotShallowEqual, !Object.shallowEqual(actual, expected), message, actual, expected);
    }

    expectEqualWithAccuracy(actual, expected, accuracy, message)
    {
        console.assert(typeof expected === "number");
        console.assert(typeof actual === "number");

        this._expect(TestHarness.ExpectationType.EqualWithAccuracy, Math.abs(expected - actual) <= accuracy, message, actual, expected, accuracy);
    }

    expectLessThan(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.LessThan, actual < expected, message, actual, expected);
    }

    expectLessThanOrEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.LessThanOrEqual, actual <= expected, message, actual, expected);
    }

    expectGreaterThan(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.GreaterThan, actual > expected, message, actual, expected);
    }

    expectGreaterThanOrEqual(actual, expected, message)
    {
        this._expect(TestHarness.ExpectationType.GreaterThanOrEqual, actual >= expected, message, actual, expected);
    }

    pass(message)
    {
        let stringifiedMessage = TestHarness.messageAsString(message);
        this.log("PASS: " + stringifiedMessage);
    }

    fail(message)
    {
        let stringifiedMessage = TestHarness.messageAsString(message);
        this.log("FAIL: " + stringifiedMessage);
    }

    passOrFail(condition, message)
    {
        if (condition)
            this.pass(message);
        else
            this.fail(message);
    }

    // Use this to expect an exception. To further examine the exception,
    // chain onto the result with .then() and add your own test assertions.
    // The returned promise is rejected if an exception was not thrown.
    expectException(work)
    {
        if (typeof work !== "function")
            throw new Error("Invalid argument to catchException: work must be a function.");

        let expectAndDumpError = (e) => {
            this.expectNotNull(e, "Should produce an exception.");
            if (!e)
                return;

            if (e instanceof Error || !(e instanceof Object))
                this.log(e.toString());
            else {
                try {
                    this.json(e);
                } catch {
                    this.log(e.constructor.name);
                }
            }
        }

        let error = null;
        let result = null;
        try {
            result = work();
        } catch (caughtError) {
            error = caughtError;
        } finally {
            // If 'work' returns a promise, it will settle (resolve or reject) by itself.
            // Invert the promise's settled state to match the expectation of the caller.
            if (result instanceof Promise) {
                return result.then((resolvedValue) => {
                    expectAndDumpError(null);
                    return Promise.reject(resolvedValue);
                }, (e) => { // Don't chain the .catch as it will log the value we just rejected.
                    expectAndDumpError(e);
                    return Promise.resolve(e);
                });
            }

            // If a promise is not produced, turn the exception into a resolved promise, and a
            // resolved value into a rejected value (since an exception was expected).
            expectAndDumpError(error);
            return error ? Promise.resolve(error) : Promise.reject(result);
        }
    }

    // Protected

    static messageAsString(message)
    {
        if (message instanceof Element)
            return message.textContent;

        return typeof message !== "string" ? JSON.stringify(message) : message;
    }

    static sanitizeURL(url)
    {
        if (!url)
            return "(unknown)";

        let lastPathSeparator = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
        let location = lastPathSeparator > 0 ? url.substr(lastPathSeparator + 1) : url;
        if (!location.length)
            location = "(unknown)";

        // Clean up the location so it is bracketed or in parenthesis.
        if (url.indexOf("[native code]") !== -1)
            location = "[native code]";

        return location;
    }

    static sanitizeStackFrame(frame, i)
    {
        // Most frames are of the form "functionName@file:///foo/bar/File.js:345".
        // But, some frames do not have a functionName. Get rid of the file path.
        let nameAndURLSeparator = frame.indexOf("@");
        let frameName = nameAndURLSeparator > 0 ? frame.substr(0, nameAndURLSeparator) : "(anonymous)";

        let lastPathSeparator = Math.max(frame.lastIndexOf("/"), frame.lastIndexOf("\\"));
        let frameLocation = lastPathSeparator > 0 ? frame.substr(lastPathSeparator + 1) : frame;
        if (!frameLocation.length)
            frameLocation = "unknown";

        // Clean up the location so it is bracketed or in parenthesis.
        if (frame.indexOf("[native code]") !== -1)
            frameLocation = "[native code]";
        else
            frameLocation = "(" + frameLocation + ")";

        return `#${i}: ${frameName} ${frameLocation}`;
    }

    sanitizeStack(stack)
    {
        if (this.suppressStackTraces)
            return "(suppressed)";

        if (!stack || typeof stack !== "string")
            return "(unknown)";

        return stack.split("\n").map(TestHarness.sanitizeStackFrame).join("\n");
    }

    // Private

    _expect(type, condition, message, ...values)
    {
        console.assert(values.length > 0, "Should have an 'actual' value.");

        if (!message || !condition) {
            values = values.map(this._expectationValueAsString.bind(this));
            message = message || this._expectationMessageFormat(type).format(...values);
        }

        if (condition) {
            this.pass(message);
            return;
        }

        message += "\n    Expected: " + this._expectedValueFormat(type).format(...values.slice(1));
        message += "\n    Actual: " + values[0];

        this.fail(message);
    }

    _expectationValueAsString(value)
    {
        let instanceIdentifier = (object) => {
            let id = this._failureObjects.get(object);
            if (!id) {
                id = this._failureObjectIdentifier++;
                this._failureObjects.set(object, id);
            }
            return "#" + id;
        };

        const maximumValueStringLength = 200;
        const defaultValueString = String(new Object); // [object Object]

        // Special case for numbers, since JSON.stringify converts Infinity and NaN to null.
        if (typeof value === "number")
            return value;

        try {
            let valueString = JSON.stringify(value);
            if (valueString.length <= maximumValueStringLength)
                return valueString;
        } catch { }

        try {
            let valueString = String(value);
            if (valueString === defaultValueString && value.constructor && value.constructor.name !== "Object")
                return value.constructor.name + " instance " + instanceIdentifier(value);
            return valueString;
        } catch {
            return defaultValueString;
        }
    }

    _expectationMessageFormat(type)
    {
        switch (type) {
        case TestHarness.ExpectationType.True:
            return "expectThat(%s)";
        case TestHarness.ExpectationType.False:
            return "expectFalse(%s)";
        case TestHarness.ExpectationType.Null:
            return "expectNull(%s)";
        case TestHarness.ExpectationType.NotNull:
            return "expectNotNull(%s)";
        case TestHarness.ExpectationType.Equal:
            return "expectEqual(%s, %s)";
        case TestHarness.ExpectationType.NotEqual:
            return "expectNotEqual(%s, %s)";
        case TestHarness.ExpectationType.ShallowEqual:
            return "expectShallowEqual(%s, %s)";
        case TestHarness.ExpectationType.NotShallowEqual:
            return "expectNotShallowEqual(%s, %s)";
        case TestHarness.ExpectationType.EqualWithAccuracy:
            return "expectEqualWithAccuracy(%s, %s, %s)";
        case TestHarness.ExpectationType.LessThan:
            return "expectLessThan(%s, %s)";
        case TestHarness.ExpectationType.LessThanOrEqual:
            return "expectLessThanOrEqual(%s, %s)";
        case TestHarness.ExpectationType.GreaterThan:
            return "expectGreaterThan(%s, %s)";
        case TestHarness.ExpectationType.GreaterThanOrEqual:
            return "expectGreaterThanOrEqual(%s, %s)";
        default:
            console.error("Unknown TestHarness.ExpectationType type: " + type);
            return null;
        }
    }

    _expectedValueFormat(type)
    {
        switch (type) {
        case TestHarness.ExpectationType.True:
            return "truthy";
        case TestHarness.ExpectationType.False:
            return "falsey";
        case TestHarness.ExpectationType.NotNull:
            return "not null";
        case TestHarness.ExpectationType.NotEqual:
        case TestHarness.ExpectationType.NotShallowEqual:
            return "not %s";
        case TestHarness.ExpectationType.EqualWithAccuracy:
            return "%s +/- %s";
        case TestHarness.ExpectationType.LessThan:
            return "less than %s";
        case TestHarness.ExpectationType.LessThanOrEqual:
            return "less than or equal to %s";
        case TestHarness.ExpectationType.GreaterThan:
            return "greater than %s";
        case TestHarness.ExpectationType.GreaterThanOrEqual:
            return "greater than or equal to %s";
        default:
            return "%s";
        }
    }
};

TestHarness.ExpectationType = {
    True: Symbol("expect-true"),
    False: Symbol("expect-false"),
    Null: Symbol("expect-null"),
    NotNull: Symbol("expect-not-null"),
    Equal: Symbol("expect-equal"),
    NotEqual: Symbol("expect-not-equal"),
    ShallowEqual: Symbol("expect-shallow-equal"),
    NotShallowEqual: Symbol("expect-not-shallow-equal"),
    EqualWithAccuracy: Symbol("expect-equal-with-accuracy"),
    LessThan: Symbol("expect-less-than"),
    LessThanOrEqual: Symbol("expect-less-than-or-equal"),
    GreaterThan: Symbol("expect-greater-than"),
    GreaterThanOrEqual: Symbol("expect-greater-than-or-equal"),
};
