<script>
    function log(msg)
    {
        // alert(msg);
        window.webkit.messageHandlers.testHandler.postMessage(msg);
    }

    function shouldBeType(_a, _type)
    {
        let exception;
        let _av;
        try {
            _av = eval(_a);
        } catch (e) {
            exception = e;
        }

        const _typev = eval(_type);
        if (_av instanceof _typev) {
            return true;
        } else {
            return false;
        }
    }

    function shouldBeCryptoKey(_a, _key)
    {
        if (!(JSON.stringify(_key.key_ops) == JSON.stringify(_a.key_ops)) || !(_key.ext == _a.ext))
            return false;
        if (_key.kty  == "oct" && _a.kty == "oct")
            return (_key.k == _a.k) && (_key.alg == _a.alg);
        if (_key.kty  == "EC" && _a.kty == "EC")
            return (_key.k == _a.k) && (_key.crv == _a.crv) && (_key.x == _a.x) && (_key.y == _a.y) && (_key.d == _a.d);
        if (_key.kty  == "RSA" && _a.kty == "RSA")
            return (_key.alg == _a.alg) && (_key.n == _a.n) && (_key.e == _a.e) && (_key.d == _a.d) && (_key.p == _a.p) && (_key.q == _a.q) && (_key.dp == _a.dp) && (_key.dq == _a.dq) && (_key.qi == _a.qi);
        return false;
    }

    // Values that are used to infer the type of a given primitive type.
    const testValues = [
        undefined,
        null,
        5, // Int
        0,
        1,
        false,
        true,
        5.5, // Double
        "Hello,World!",
        ""
    ];

    // Values that are used to infer the type of a given Boolean/String type.
    const testTypeValues = [
        { item: new Boolean(true), type: "Boolean", value: true },
        { item: new Boolean(false), type: "Boolean", value: false },
        { item: new String(), type: "String", value: "" }
    ];

    // Values are in JWK formats.
    const testCryptoKeyValues = [
        { kty: "oct", k: "YWJjZGVmZ2gxMjM0NTY3OA", alg: "A128CBC", use: "enc", key_ops: ['decrypt', 'encrypt', 'unwrapKey', 'wrapKey'], ext: true },
        { kty: "EC", use: "sig", ext: true, crv: "P-256", x: "1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA", y: "9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI", key_ops: ['verify'] },
        { kty: "EC", use: "sig", ext: true, key_ops: ["sign"], crv: "P-256", x: "1FSVWieTvikFkG1NOyhkUCaMbdQhxwH6aCu4Ez-sRtA", y: "9jmNTLqM4cjBhdAnHcNI9YQV3O8LFmo-EdZWk8ntAaI", d: "ppxBSov3N8_AUcisAuvmLV4yE8e_L_BLE8bZb9Z1Xjg" },
        { kty: "oct", k: "YWJjZGVmZ2gxMjM0NTY3OA", alg: "HS256", use: "sig", key_ops: ["sign", "verify"], ext: true, },
        { kty: "RSA", alg: "PS256", use: "sig", key_ops: ["verify"], ext: true, n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw", e: "AQAB" },
        { kty: "RSA", alg: "PS1", use: "sig", key_ops: ["sign"], ext: true, n: "rcCUCv7Oc1HVam1DIhCzqknThWawOp8QLk8Ziy2p10ByjQFCajoFiyuAWl-R1WXZaf4xitLRracT9agpzIzc-MbLSHIGgWQGO21lGiImy5ftZ-D8bHAqRz2y15pzD4c4CEou7XSSLDoRnR0QG5MsDhD6s2gV9mwHkrtkCxtMWdBi-77as8wGmlNRldcOSgZDLK8UnCSgA1OguZ989bFyc8tOOEIb0xUSfPSz3LPSCnyYz68aDjmKVeNH-ig857OScyWbGyEy3Biw64qun3juUlNWsJ3zngkOdteYWytx5Qr4XKNs6R-Myyq72KUp02mJDZiiyiglxML_i3-_CeecCw", e: "AQAB", d: "eNLS37aCz7RXSNPD_DtLBJ6j5T8cSxdzRBCjPaI6WcGqJp16lq3UTwuoDLAqlA9oGYm238dsIWpuucP_lQtbWe-7SpxoI6_vmYGf7YVUHv1-DF9qiOmSrMmdxMnVOzYXY8RaT6thPjn_J5cfLV2xI_LwsrMtmpdSyNlgX0zTUhwtuahgAKMEChYjH2EnjHdHw6sY2-wApdcQI7ULE0oo5RzbQZpmuhcN9hiBc0L3hhF0qo50mbl02_65_GQ7DpVkXBxNgRBLzlPabmzzG2oAhfefLgYmSC1opaCkXE6vRWQNWNL45RZNZFYM3uoJghOMqGeocM0BpjdChHrPOlFvSQ", p: "4miTuAjKMeH5uJ5KB397QUwhbkYEgSbcA2mifmSkvE2018gb55qkBHK1eVryf1_m43LNlc6O_ak6gfzdZIZvS5NCGjPl0q09plUpu8qFOSspBwA67qGH76lFlZLn_d4yglS7wfLru4_5Ys8qLLs-DqVLviwposOnyyWqwM5AXp0", q: "xHYrzkivtmnz_sGchnWGc0q-pDOkKicptRpv2pMFIIXxnFX5aMeEXIZjVujXtwUy1UlFIN2GZJSvy5KJ79mu_XyNnFHMzedH-A3ee3u8h1UUrZF-vUu1_e4U_x67NN1dedzUSKynN7pFl3OkuShMBWGV-cwzOPdcVAfVuZlxUMc", dp: "fBzDzYDUBmBQGop7Hn0dvf_T27V6RqpctWo074CQZcFbP2atFVtKSj3viWT3xid2VHzcgiDHdfpM3nEVlEO1wwIonGCSvdjGEOZiiFVOjrZAOVxA8guOjyyFvqbXke06VwPIIVvfKeSU2zuhbP__1tt6F_fxow4Kb2xonGT0GGk", dq: "jmE2DiIPdhwDgLXAQpIaBqQ81bO3XfVT_LRULAwwwwlPuQV148H04zlh9TJ6Y2GZHYokV1U0eOBpJxfkb7dLYtpJpuiBjRf4yIUEoGlkkI_QlJnFSFr-YjGRdfNHqWBkxlSMZL770R9mIATndGkH7z5x-r9KwBZFC4FCG2hg_zE", qi: "YCX_pLwbMBA1ThVH0WcwmnytqNcrMCEwTm7ByA2eU6nWbQrULvf7m9_kzfLUcjsnpAVlBQG5JMXMy0Sq4ptwbywsa5-G8KAOOOR2L3v4hC-Eys9ftgFM_3i0o40eeQH4b3haPbntrIeMg8IzlOuVYKf9-2QuKDoWeRdd7NsdxTk" }
    ];

    indexedDB.deleteDatabase("backward_compatibility");
    const openRequest = indexedDB.open("backward_compatibility");
    openRequest.onupgradeneeded = function(event) {
        // This objectStore stores elements that we only need to check its type to determine its serialization tag.
        event.target.result.createObjectStore("type");
        // This objectStore stores elements that we need to check its value to determine its serialization tag.
        event.target.result.createObjectStore("value", { autoIncrement : true });
        // This objectStore stores elements that we need to check both its type and its value to determine its serialization tag.
        event.target.result.createObjectStore("typeValue", { autoIncrement : true });
        // This objectStore stores crypto keys.
        event.target.result.createObjectStore("cryptoKey", { autoIncrement : true });
    };
    openRequest.onerror = function(event) {
        log("Error: " + event.target.error.name);
    };
    openRequest.onsuccess = function(event) {
        db = event.target.result;
        storeType();
    };

    function storeType()
    {
        const transaction = db.transaction("type", "readwrite");
        transaction.onerror = function(event) {
            log("Error: " + event.target.error.name);
        };
        transaction.oncomplete = function(event) { storeValue(); };

        const objectStore = transaction.objectStore("type");
        // The key of an item is the type of its value, hence we could determine type mismatch, i.e. serialization tag reorder
        // simply by using an item's key and value.
        objectStore.add([1, 2], "Array");
        objectStore.add({ property: null }, "Object");
        objectStore.add(new Date(), "Date");
        objectStore.add(new File(["foo"], "foo.txt"), "File");
        objectStore.add(new ImageData(100, 100), "ImageData");
        objectStore.add(new Blob(["foo"]), "Blob");
        objectStore.add(new RegExp(''), "RegExp");
        objectStore.add(new ArrayBuffer(1), "ArrayBuffer");
        objectStore.add(new String(''), "String");
        objectStore.add(new Number(12), "Number");
        objectStore.add(new Set([1, 2]), "Set");
        objectStore.add(new Map(), "Map");
        // Typed arrays
        objectStore.add(new Int8Array(), "Int8Array");
        objectStore.add(new Uint8Array(), "Uint8Array");
        objectStore.add(new Uint8ClampedArray(), "Uint8ClampedArray");
        objectStore.add(new Int16Array(), "Int16Array");
        objectStore.add(new Uint16Array(), "Uint16Array");
        objectStore.add(new Int32Array(), "Int32Array");
        objectStore.add(new Uint32Array(), "Uint32Array");
        objectStore.add(new Float32Array(), "Float32Array");
        objectStore.add(new Float64Array(), "Float64Array");
    }

    function storeValue()
    {
        const transaction = db.transaction("value", "readwrite");
        transaction.onerror = function(event) {
            log("Error: " + event.target.error.name);
        };
        transaction.oncomplete = function(event) { storeTypeValue(); };

        const objectStore = transaction.objectStore("value");
        // Here we store values in the test matrix in order and read them in order to see if any mismatch happens.
        for (let i = 0; i < testValues.length; i++)
            objectStore.add(testValues[i]);
    }

    function storeTypeValue()
    {
        const transaction = db.transaction("typeValue", "readwrite");
        transaction.onerror = function(event) {
            log("Error: " + event.target.error.name);
        };
        transaction.oncomplete = function(event) { storeCryptoKey(); };

        const objectStore = transaction.objectStore("typeValue");
        // Here we store items in the test matrix in order and read them in order to see if any mismatches its type and value.
        for (let i = 0; i < testTypeValues.length; i++)
            objectStore.add(testTypeValues[i].item);
    }

    async function storeCryptoKey()
    {
        const transaction = db.transaction("cryptoKey", "readwrite");
        transaction.onerror = function(event) {
            log("Error: " + event.target.error.name);
        };
        transaction.oncomplete = function(event) { readType(); };

        const objectStore = transaction.objectStore("cryptoKey");
        // Here we store items in the test matrix in order and read them in order to see if any mismatches its type and value.
        let cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[0], "aes-cbc", true, ["encrypt", "decrypt", "wrapKey", "unwrapKey"]);
        objectStore.add(cryptoKey);
        cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[1], { name: "ECDSA", namedCurve: "P-256" }, true, ['verify']);
        objectStore.add(cryptoKey);
        cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[2], { name: "ECDSA", namedCurve: "P-256" }, true, ["sign"]);
        objectStore.add(cryptoKey);
        cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[3], {name: "hmac", hash: "sha-256"}, true, ["sign", "verify"]);
        objectStore.add(cryptoKey);
        cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[4], {name: "RSA-PSS", hash: "SHA-256"}, true, ["verify"]);
        objectStore.add(cryptoKey);
        cryptoKey = await crypto.subtle.importKey("jwk", testCryptoKeyValues[5], {name: "RSA-PSS", hash: "SHA-1"}, true, ["sign"]);
        objectStore.add(cryptoKey);
    }

    let result = true;
    function readType()
    {
        const objectStore = db.transaction("type").objectStore("type");
        objectStore.openCursor().onsuccess = function(event) {
            cursor = event.target.result;
            if (cursor) {
                result = result && shouldBeType("cursor.value", cursor.key);
                cursor.continue();
            } else
                readValue();
        };
    }

    function readValue()
    {
        const objectStore = db.transaction("value").objectStore("value");
        objectStore.openCursor().onsuccess = function(event) {
            cursor = event.target.result;
            if (cursor) {
                result = result && (cursor.value === testValues[cursor.key - 1]);
                cursor.continue();
            } else
                readTypeValue();
        };
    }

    function readTypeValue()
    {
        const objectStore = db.transaction("typeValue").objectStore("typeValue");
        objectStore.openCursor().onsuccess = function(event) {
            cursor = event.target.result;
            if (cursor) {
                result = result && shouldBeType("cursor.value", testTypeValues[cursor.key - 1].type) && (cursor.value == testTypeValues[cursor.key - 1].value);
                cursor.continue();
            } else {
                readCryptoKey();
            }
        };
    }

    async function readCryptoKey()
    {
        const objectStore = db.transaction("cryptoKey").objectStore("cryptoKey");
        objectStore.openCursor().onsuccess = async function(event) {
            cursor = event.target.result;
            if (cursor) {
                const jwkKey = await crypto.subtle.exportKey("jwk", cursor.value);
                result = result && shouldBeCryptoKey(jwkKey, testCryptoKeyValues[cursor.key - 1]);
                cursor.continue();
            } else {
                if (result)
                    log("Pass");
                else
                    log("Fail");
            }
        };
    }
</script>
