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

import * as assert from './assert.js';
import LowLevelBinary from './LowLevelBinary.js';
import * as WASM from './WASM.js';

const put = (bin, type, value) => bin[type](value);

const putResizableLimits = (bin, initial, maximum, shared = false) => {
    assert.truthy(typeof initial === "number", "We expect 'initial' to be an integer");
    let flag = 0;
    if (typeof maximum === "number") {
        flag |= 0b01;
    } else {
        assert.truthy(typeof maximum === "undefined", "We expect 'maximum' to be an integer if it's defined");
    }
    if (shared) {
        assert.truthy(typeof maximum === "number", "We expect 'maximum' to be an integer if shared is true");
        flag |= 0b10;
    }

    put(bin, "uint8", flag);
    put(bin, "varuint32", initial);
    if (flag & 0b01)
        put(bin, "varuint32", maximum);
};

const putTable = (bin, {initial, maximum, element}) => {
    assert.truthy(WASM.isValidType(element), "We expect 'element' to be a valid type. It was: " + element);
    put(bin, "varint7", WASM.typeValue[element]);

    putResizableLimits(bin, initial, maximum);
};

const valueType = WASM.description.type.i32.type

const putGlobalType = (bin, global) => {
    put(bin, valueType, WASM.typeValue[global.type]);
    put(bin, "uint8", global.mutability);
};

const putOp = (bin, op) => {
    put(bin, "uint8", op.value);
    if (WASM.description.opcode[op.name].extendedOp)
        put(bin, "uint8", WASM.description.opcode[op.name].extendedOp);
    if (op.arguments.length !== 0)
        throw new Error(`Unimplemented: arguments`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706

    switch (op.name) {
    default:
        for (let i = 0; i < op.immediates.length; ++i) {
            const type = WASM.description.opcode[op.name].immediate[i].type
            if (!bin[type])
                throw new TypeError(`Unknown type: ${type} in op: ${op.name}`);
            put(bin, type, op.immediates[i]);
        }
        break;
    case "i32.const": {
        assert.eq(op.immediates.length, 1);
        let imm = op.immediates[0];
        // Do a static cast to make large int32s signed.
        if (imm >= 2 ** 31)
            imm = imm - (2 ** 32);
        put(bin, "varint32", imm);
        break;
    }
    case "br_table":
        put(bin, "varuint32", op.immediates.length - 1);
        for (let imm of op.immediates)
            put(bin, "varuint32", imm);
        break;
    }
};

const putInitExpr = (bin, expr) => {
    if (expr.op == "ref.null")
        putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.reftype], arguments: [] });
    else
        putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.initValue], arguments: [] });
    putOp(bin, { value: WASM.description.opcode.end.value, name: "end", immediates: [], arguments: [] });
};

const emitters = {
    Type: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const entry of section.data) {
            put(bin, "varint7", WASM.typeValue["func"]);
            put(bin, "varuint32", entry.params.length);
            for (const param of entry.params)
                put(bin, "varint7", WASM.typeValue[param]);
            if (entry.ret === "void")
                put(bin, "varuint1", 0);
            else {
                put(bin, "varuint1", 1);
                put(bin, "varint7", WASM.typeValue[entry.ret]);
            }
        }
    },
    Import: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const entry of section.data) {
            put(bin, "string", entry.module);
            put(bin, "string", entry.field);
            put(bin, "uint8", WASM.externalKindValue[entry.kind]);
            switch (entry.kind) {
            default: throw new Error(`Implementation problem: unexpected kind ${entry.kind}`);
            case "Function": {
                put(bin, "varuint32", entry.type);
                break;
            }
            case "Table": {
                putTable(bin, entry.tableDescription);
                break;
            }
            case "Memory": {
                let {initial, maximum, shared} = entry.memoryDescription;
                putResizableLimits(bin, initial, maximum, shared);
                break;
            };
            case "Global":
                putGlobalType(bin, entry.globalDescription);
                break;
            case "Exception":
                put(bin, "varuint32", entry.tag);
                put(bin, "varuint32", entry.type);
                break;
            }
        }
    },

    Function: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const signature of section.data)
            put(bin, "varuint32", signature);
    },

    Table: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const {tableDescription} of section.data) {
            putTable(bin, tableDescription);
        }
    },

    Memory: (section, bin) => {
        // Flags, currently can only be [0,1]
        put(bin, "varuint1", section.data.length);
        for (const memory of section.data)
            putResizableLimits(bin, memory.initial, memory.maximum, memory.shared);
    },

    Global: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const global of section.data) {
            putGlobalType(bin, global);
            putInitExpr(bin, global)
        }
    },

    Export: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const entry of section.data) {
            put(bin, "string", entry.field);
            put(bin, "uint8", WASM.externalKindValue[entry.kind]);
            switch (entry.kind) {
            case "Global":
            case "Function":
            case "Memory":
            case "Table":
            case "Exception":
                put(bin, "varuint32", entry.index);
                break;
            default: throw new Error(`Implementation problem: unexpected kind ${entry.kind}`);
            }
        }
    },
    Start: (section, bin) => {
        put(bin, "varuint32", section.data[0]);
    },
    Element: (section, bin) => {
        const data = section.data;
        put(bin, "varuint32", data.length);
        for (const {tableIndex, offset, elemkind, functionIndices} of data) {
            let flags = tableIndex == 0 ? 0 : 2;
            put(bin, "uint8", flags);

            if (flags == 2) {
              put(bin, "varuint32", tableIndex);
            }

            let initExpr;
            if (typeof offset === "number")
                initExpr = {op: "i32.const", initValue: offset};
            else
                initExpr = offset;
            putInitExpr(bin, initExpr);

            if (flags == 2) {
              put(bin, "uint8", elemkind);
            }

            put(bin, "varuint32", functionIndices.length);
            for (const functionIndex of functionIndices)
                put(bin, "varuint32", functionIndex);
        }
    },

    Code: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const func of section.data) {
            let funcBin = bin.newPatchable("varuint32");
            const localCount = func.locals.length - func.parameterCount;
            put(funcBin, "varuint32", localCount);
            for (let i = func.parameterCount; i < func.locals.length; ++i) {
                put(funcBin, "varuint32", 1);
                put(funcBin, "varint7", WASM.typeValue[func.locals[i]]);
            }

            for (const op of func.code)
                putOp(funcBin, op);

            funcBin.apply();
        }
    },

    Data: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const datum of section.data) {
            put(bin, "varuint32", datum.index);
            // FIXME allow complex init_expr here. https://bugs.webkit.org/show_bug.cgi?id=165700
            // For now we only handle i32.const as offset.
            put(bin, "uint8", WASM.description.opcode["i32.const"].value);
            put(bin, WASM.description.opcode["i32.const"].immediate[0].type, datum.offset);
            put(bin, "uint8", WASM.description.opcode["end"].value);
            put(bin, "varuint32", datum.data.length);
            for (const byte of datum.data)
                put(bin, "uint8", byte);
        }
    },

    Exception: (section, bin) => {
        put(bin, "varuint32", section.data.length);
        for (const exn of section.data) {
            put(bin, "varuint32", exn.tag);
            put(bin, "varuint32", exn.type);
        }
    },
};

export const Binary = (preamble, sections) => {
    let wasmBin = new LowLevelBinary();
    for (const p of WASM.description.preamble)
        put(wasmBin, p.type, preamble[p.name]);
    for (const section of sections) {
        put(wasmBin, WASM.sectionEncodingType, section.id);
        let sectionBin = wasmBin.newPatchable("varuint32");
        const emitter = emitters[section.name];
        if (emitter)
            emitter(section, sectionBin);
        else {
            // Unknown section.
            put(sectionBin, "string", section.name);
            for (const byte of section.data)
                put(sectionBin, "uint8", byte);
        }
        sectionBin.apply();
    }
    wasmBin.trim();
    return wasmBin;
};
