/*
 * Copyright 2017 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

'use strict';

let testNum = (function() {
    let count = 1;
    return function() {
        return `#${count++} `;
    }
})();

// WPT's assert_throw uses a list of predefined, hardcoded known errors. Since
// it is not aware of the WebAssembly error types (yet), implement our own
// version.
function assertThrows(func, err) {
    let caught = false;
    try {
        func();
    } catch(e) {
        assert_true(e instanceof err, `expected ${err.name}, observed ${e.constructor.name}`);
        caught = true;
    }
    assert_true(caught, testNum() + "assertThrows must catch any error.")
}

/******************************************************************************
***************************** WAST HARNESS ************************************
******************************************************************************/

// For assertions internal to our test harness.
function _assert(x) {
    if (!x) {
        throw new Error(`Assertion failure: ${x}`);
    }
}

// A simple sum type that can either be a valid Value or an Error.
function Result(type, maybeValue) {
    this.value = maybeValue;
    this.type = type;
};

Result.VALUE = 'VALUE';
Result.ERROR = 'ERROR';

function ValueResult(val) { return new Result(Result.VALUE, val); }
function ErrorResult(err) { return new Result(Result.ERROR, err); }

Result.prototype.isError = function() { return this.type === Result.ERROR; }

const EXPECT_INVALID = false;

/* DATA **********************************************************************/

let soft_validate = true;

let $$;

// Default imports.
var registry = {};

// Resets the registry between two different WPT tests.
function reinitializeRegistry() {
    if (typeof WebAssembly === 'undefined')
        return;

    registry = {
        spectest: {
            print: print,
            global: 666,
            table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'funcref'}),
            memory: new WebAssembly.Memory({initial: 1, maximum: 2})
        }
    };
}

reinitializeRegistry();

/* WAST POLYFILL *************************************************************/

function binary(bytes) {
    let buffer = new ArrayBuffer(bytes.length);
    let view = new Uint8Array(buffer);
    for (let i = 0; i < bytes.length; ++i) {
        view[i] = bytes.charCodeAt(i);
    }
    return buffer;
}

/**
 * Returns a compiled module, or throws if there was an error at compilation.
 */
function module(bytes, valid = true) {
    let buffer = binary(bytes);
    let validated;

    try {
        validated = WebAssembly.validate(buffer);
    } catch (e) {
        throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`);
    }

    if (validated !== valid) {
        // Try to get a more precise error message from the WebAssembly.CompileError.
        let err = '';
        try {
            new WebAssembly.Module(buffer);
        } catch (e) {
            if (e instanceof WebAssembly.CompileError)
                throw new WebAssembly.CompileError(`WebAssembly.validate error: ${e.toString()}${e.stack}\n`);
            else
                throw new Error(`WebAssembly.validate throws ${typeof e}: ${e}${e.stack}`);
        }
        throw new Error(`WebAssembly.validate was expected to fail, but didn't`);
    }

    let module;
    try {
        module = new WebAssembly.Module(buffer);
    } catch(e) {
        if (valid)
            throw new Error('WebAssembly.Module ctor unexpectedly throws ${typeof e}: ${e}${e.stack}');
        throw e;
    }

    return module;
}

function uniqueTest(func, desc) {
    test(func, testNum() + desc);
}

function assert_invalid(bytes) {
    uniqueTest(() => {
        try {
            module(bytes, /* valid */ false);
            throw new Error('did not fail');
        } catch(e) {
            assert_true(e instanceof WebAssembly.CompileError, "expected invalid failure:");
        }
    }, "A wast module that should be invalid or malformed.");
}

const assert_malformed = assert_invalid;

function assert_soft_invalid(bytes) {
    uniqueTest(() => {
        try {
            module(bytes, /* valid */ soft_validate);
            if (soft_validate)
                throw new Error('did not fail');
        } catch(e) {
            if (soft_validate)
                assert_true(e instanceof WebAssembly.CompileError, "expected soft invalid failure:");
        }
    }, "A wast module that *could* be invalid under certain engines.");
}

function instance(bytes, imports = registry, valid = true) {
    if (imports instanceof Result) {
        if (imports.isError())
            return imports;
        imports = imports.value;
    }

    let err = null;

    let m, i;
    try {
        let m = module(bytes);
        i = new WebAssembly.Instance(m, imports);
    } catch(e) {
        err = e;
    }

    if (valid) {
        uniqueTest(() => {
            let instantiated = err === null;
            if (!instantiated) print(err);
            assert_true(instantiated, err);
        }, "module successfully instantiated");
    }

    return err !== null ? ErrorResult(err) : ValueResult(i);
}

function register(name, instance) {
    _assert(instance instanceof Result);

    if (instance.isError())
        return;

    registry[name] = instance.value.exports;
}

function call(instance, name, args) {
    _assert(instance instanceof Result);

    if (instance.isError())
        return instance;

    let err = null;
    let result;
    try {
        result = instance.value.exports[name](...args);
    } catch(e) {
        err = e;
    }

    return err !== null ? ErrorResult(err) : ValueResult(result);
};

function get(instance, name) {
    _assert(instance instanceof Result);

    if (instance.isError())
        return instance;

    return ValueResult(instance.value.exports[name]);
}

function exports(name, instance) {
    _assert(instance instanceof Result);

    if (instance.isError())
        return instance;

    return ValueResult({ [name]: instance.value.exports });
}

function run(action) {
    print("running new test: " + (new Error()).stack);
    let result = action();

    _assert(result instanceof Result);

    uniqueTest(() => {
        if (result.isError())
            throw result.value;
    }, "A wast test that runs without any special assertion.");
}

function assert_unlinkable(bytes) {
    let result = instance(bytes, registry, EXPECT_INVALID);

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(result.isError(), 'expected error result');
        if (result.isError()) {
            let e = result.value;
            assert_true(e instanceof WebAssembly.LinkError, `expected link error, observed ${e}:`);
        }
    }, "A wast module that is unlinkable.");
}

function assert_uninstantiable(bytes) {
    let result = instance(bytes, registry, EXPECT_INVALID);

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(result.isError(), 'expected error result');
        if (result.isError()) {
            let e = result.value;
            assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`);
        }
    }, "A wast module that is uninstantiable.");
}

function assert_trap(action) {
    let result = action();

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(result.isError(), 'expected error result');
        if (result.isError()) {
            let e = result.value;
            assert_true(e instanceof WebAssembly.RuntimeError, `expected runtime error, observed ${e}:`);
        }
    }, "A wast module that must trap at runtime.");
}

let StackOverflow;
try { (function f() { 1 + f() })() } catch (e) { StackOverflow = e.constructor }

function assert_exhaustion(action) {
    let result = action();

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(result.isError(), 'expected error result');
        if (result.isError()) {
            let e = result.value;
            assert_true(e instanceof StackOverflow, `expected stack overflow error, observed ${e}:`);
        }
    }, "A wast module that must exhaust the stack space.");
}

function assert_return(action, ...expectedValues) {
    if (expectedValues[0] instanceof Result) {
        if (expectedValues[0].isError())
            return;
        expected = expected.value;
    }

    let result = action();

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(!result.isError(), `expected success result, got: ${result.value}.`);
        if (!result.isError()) {
            assert_equals(result.value, expectedValues.length < 2 ? expectedValues[0] : expectedValues);
        };
    }, "A wast module that must return a particular value.");
};

function assert_return_nan(action) {
    let result = action();

    _assert(result instanceof Result);

    uniqueTest(() => {
        assert_true(!result.isError(), 'expected success result');
        if (!result.isError()) {
            assert_true(Number.isNaN(result.value), `expected NaN, observed ${result.value}.`);
        };
    }, "A wast module that must return NaN.");
}
