/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

// odata-tests.js
(function (window, undefined) {

    var cleanDomStorage = function () {
        /** Cleans all the data saved in the browser's DOM Storage.
        */
        if (window.localStorage) {
            window.localStorage.clear();
        }
    };

    var cleanMemoryStorage = function () {
        /** Clean memory storage is a no op.
        */
    };

    var cleanIndexedDbStorage = function () {
        var stores = this.stores;
        $.each(stores, function (_, store) {
            store.close();
        });

        djstest.wait(function (done) {
            djstest.cleanStoreOnIndexedDb(stores, done);
        });
    };

    var canCreateMemoryStore = function () {
        /** Checks whether memory storage is supported by the browser.
         * @returns {boolean} True
         */
        return true;
    };

    var canCreateDomStore = function () {
        /** Checks whether Web Storage (DOM Storage) is supported by the browser.
         * @returns {boolean} True if DOM Storage is supported by the browser; false otherwise.
         */
        return !!window.localStorage;
    };

    var canCreateIndexedDb = function () {
        /** Checks whether Web Storage (DOM Storage) is supported by the browser.
         * @returns {Boolean} True if IndexedDB is supported by the browser, false otherwise.
         */
        return !!djstest.indexedDB;
    };

    var canCreateStore = function (mechanism) {
        /** Determines whether a particular mechanism is supported by the browser.
         * @param {String} mechanism - Mechanism name.
         * @returns {Boolean} True if the mechanism is supported by the browser; otherwise false.
         */
        var implementation = mechanismImplementations[mechanism];
        return implementation && implementation.canCreate();
    }
    var makeUnexpectedErrorHandler = function (fail) {
        return function (err) {
            djstest.fail("error: " + err.name + " -- message: " + err.message);
            fail();
        };
    };

    var testJobDone = function (succeeded) {
        if (!succeeded) {
            djstest.fail("Job completed but some of the functions it called failed");
        }
        djstest.done();
    };

    var mechanismImplementations = {
        indexeddb: { factory: odatajs.IndexedDBStore, canCreate: canCreateIndexedDb, cleanup: cleanIndexedDbStorage },
        dom: { factory: odatajs.DomStore, canCreate: canCreateDomStore, cleanup: cleanDomStorage },
        memory: { factory: odatajs.MemoryStore, canCreate: canCreateMemoryStore, cleanup: cleanMemoryStorage }
    };

    var oldWindowOnError;

    for (var mechanism in mechanismImplementations) {
        module("Unit", {
            mechanism: mechanism,
            createStore: function (name) {
                var store = odatajs.store.createStore(name + "_" + this.mechanism, this.mechanism);
                this.stores.push(store);
                return store;
            },
            setup: function () {
                this.stores = [];
                mechanismImplementations[this.mechanism].cleanup.call(this);

                // FireFox 7.0.1 bubbles an error event when there is an IndexedDB error, even when the error has been handled graciously.
                // This is a work around to keep QUnit from reporting false failures in IndexedDB negative tests.
                if (this.mechanism === "indexeddb") {
                    oldWindowOnError = window.onerror;
                    window.onerror = null;
                }
            },
            teardown: function () {
                mechanismImplementations[this.mechanism].cleanup.call(this);
                this.stores = [];

                // Restore QUnit's onerror handler.
                if (this.mechanism === "indexeddb") {
                    window.onerror = oldWindowOnError;
                }
            }
        });

        if (!canCreateStore(mechanism)) {
            djstest.addTest(function (mechanism) {
                djstest.expectException(function () {
                    mechanismImplemenatations[mechanism].factory.create("my horrible not working store");
                });
                djstest.done();
            }, "Local storage mechanism " + mechanism + " not supported by this browser", mechanism);
        } else {

            djstest.addTest(function storeAddTest(mechanism) {
                var tuples = [
                    { key: "null", value: null },
                    { key: "undefined", value: undefined },
                    { key: "number", value: 12345.678 },
                    { key: "string", value: "String value" },
                    { key: "date", value: new Date() },
                    { key: "object", value: { p1: 1234, nested: { p1: "a", p2: "b"}} },
                    { key: "array", value: [1, 2, 3, 4, 5] },
                    { key: "key1", value: "some value" },
                    { key: "key1", value: "this should fail", error: true },
                    { key: ["key", "key2"], value: ["value", "value2"], error: mechanism !== "indexeddb" },
                    { key: ["key6", "key7", "key6"], value: ["value", "value2", "value3"], error: true }
                ];

                var store = this.createStore("store1");
                var job = new djstest.Job();

                $.each(tuples, function (_, tuple) {
                    job.queue(function task(success, fail) {

                        var unexpectedError = makeUnexpectedErrorHandler(fail);
                        djstest.log("running task");

                        store.add(tuple.key, tuple.value,
                            function (key, value) {
                                djstest.assertAreEqual(key, tuple.key, "Keys match for " + mechanism + " - key = " + key.toString());
                                djstest.assertAreEqualDeep(value, tuple.value, "Values match for " + mechanism + " - key = " + key.toString());

                                job.queueNext(function (success, fail) {
                                    store.read(tuple.key, function (key, value) {
                                        djstest.assertAreEqualDeep(value, tuple.value, "Key: " + key + " is present in the store");
                                        success();
                                    }, makeUnexpectedErrorHandler(fail));
                                });
                                success();
                            },
                            function (err) {
                                if (!tuple.error) {
                                    unexpectedError(err);
                                } else {
                                    djstest.pass("error handler was called as expected");
                                    success();
                                }
                            });
                    });
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });

            }, "Store Add Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeAddOrUpdateTest(mechanism) {
                var tuples = [
                    { key: "null", value: null },
                    { key: "undefined", value: undefined },
                    { key: "number", value: 12345.678 },
                    { key: "string", value: "String value" },
                    { key: "date", value: new Date() },
                    { key: "object", value: { p1: 1234, nested: { p1: "a", p2: "b"}} },
                    { key: "array", value: [1, 2, 3, 4, 5] },
                    { key: "key1", value: "some value" },
                    { key: "key1", value: "this should not fail" },
                    { key: ["key", "key2", "key3"], value: ["value", "value2", "value3"], error: mechanism !== "indexeddb" },
                    { key: ["key", "key2", "key3"], value: ["value4", "value5", "value6"], error: mechanism !== "indexeddb" },
                    { key: "key1", value: 456 }
                ];

                var store = this.createStore("store2");
                var job = new djstest.Job();

                $.each(tuples, function (_, tuple) {
                    job.queue(function (success, fail) {

                        var unexpectedError = makeUnexpectedErrorHandler(fail);

                        store.addOrUpdate(tuple.key, tuple.value,
                            function (key, value) {
                                djstest.assert(!tuple.error, "success should be called");
                                djstest.assertAreEqual(key, tuple.key, "Keys match");
                                djstest.assertAreEqualDeep(value, tuple.value, "Values match");

                                store.read(tuple.key, function (key, value) {
                                    djstest.assertAreEqual(key, tuple.key, "Keys match");
                                    djstest.assertAreEqualDeep(value, tuple.value, "Values match");
                                    success();
                                }, unexpectedError);
                            },
                            function (err) {
                                if (!tuple.error) {
                                    unexpectedError(err);
                                } else {
                                    djstest.pass("error handler was called as expected");
                                    success();
                                }
                            });
                    });
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Add or Update Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeContainsTest(mechanism) {
                var store = this.createStore("store3");
                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add("Key1", "Some value", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.contains("Key1", function (contained) {
                        djstest.assert(contained, "Key is present in the store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.contains("Key2", function (contained) {
                        djstest.assert(!contained, "Key is not present in the store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });

            }, "Store Contains Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeGetAllKeysTest(mechanism) {
                var store = this.createStore("store4");
                var store2 = this.createStore("store4_1");

                var expectedKeys = [];
                var job = new djstest.Job();

                var i;
                for (i = 1; i <= 20; i++) {
                    (function (i) {
                        job.queue(function (success, fail) {
                            store.add(i.toString(), "value" + i, success, makeUnexpectedErrorHandler(fail));
                        });

                        job.queue(function (success, fail) {
                            store2.add((i + 20).toString(), "value" + (i + 20), success, makeUnexpectedErrorHandler(fail));
                        });
                    })(i);

                    expectedKeys.push(i.toString());
                }

                job.queue(function (success, fail) {
                    store.getAllKeys(function (keys) {
                        expectedKeys.sort();
                        keys.sort();
                        djstest.assertAreEqualDeep(keys, expectedKeys, "All expected keys where returned");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    store2.close();
                    testJobDone(succeeded);
                });
            }, "Store Get All Keys Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeReadTest(mechanism) {
                var tuples = [
                    { key: "null", value: null },
                    { key: "undefined", value: undefined },
                    { key: "number", value: 12345.678 },
                    { key: "string", value: "String value" },
                    { key: "date", value: new Date() },
                    { key: "dateOffset", value: (function () {
                        var d = new Date();
                        d.__type = "Edm.DateTimeOffset";
                        d.__offset = "+03:30";
                        return d;
                    })()
                    },
                    { key: "complexDate", value: (function () {
                        var d = new Date();
                        d.nestedDate = new Date();
                        d.nestedDate.__type = "Edm.DateTimeOffset";
                        d.nestedDate.__offset = "+03:30";
                        return d;
                    })()
                    },
                    { key: "object", value: { p1: 1234, nested: { p1: "a", p2: "b", p3: new Date()}} },
                    { key: "array", value: [1, 2, 3, 4, 5] }
                ];

                var store = this.createStore("store5");
                var job = new djstest.Job();

                $.each(tuples, function (_, tuple) {
                    job.queue(function (success, fail) {
                        store.add(tuple.key, tuple.value,
                            function () {
                                job.queue(function (success, fail) {
                                    store.read(tuple.key, function (key, value) {
                                        djstest.assertAreEqual(key, tuple.key, "Keys match");
                                        djstest.assertAreEqualDeep(value, tuple.value, "Values match");
                                        success();
                                    }, makeUnexpectedErrorHandler(fail));
                                });
                                success();
                            },
                           function (err) {
                               if (!tuple.error) {
                                   djstest.fail(err.message);
                                   fail();
                               } else {
                                   djstest.pass("error handler was called as expected");
                                   success();
                               }
                           });
                    });
                });

                job.queue(function (success, fail) {
                    store.read("Unknown key", function (key, value) {
                        djstest.assertAreEqual(value, undefined, "Store get returns undefined for keys that do not exist in the store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });

            }, "Store Read Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeReadArrayTest(mechanism) {
                var makeError = function (success, fail) {
                    return function (err) {
                        if (mechanism !== "indexeddb") {
                            djstest.pass("Error callback called as expected");
                            success();
                        } else {
                            djstest.fail(err.message);
                            fail();
                        }
                    };
                };

                var store = this.createStore("store6");
                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add(["key", "key2", "key3"], ["value", "value2", "value3"], success, makeError(success, fail));
                });

                job.queue(function (success, fail) {
                    store.read(["key", "key2", "key3"], function (keys, values) {
                        djstest.assertAreEqualDeep(keys, ["key", "key2", "key3"]);
                        djstest.assertAreEqualDeep(values, ["value", "value2", "value3"]);
                        success();
                    }, makeError(success, fail));
                });

                job.queue(function (success, fail) {
                    store.read(["key", "badkey"], function (keys, values) {
                        djstest.assertAreEqualDeep(keys, ["key", "badkey"]);
                        djstest.assertAreEqualDeep(values, ["value", undefined]);
                        success();
                    }, makeError(success, fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Read Array Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeRemoveTest(mechanism) {
                var store = this.createStore("store7");
                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add("Key1", "Some value", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.add("Key2", "Some value", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.remove("Key1", function () {
                        djstest.pass("Key1 was removed from the store")
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.contains("Key1", function (contained) {
                        djstest.assert(!contained, "Key1 is not present in the store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.remove("Key that has never been added", function () {
                        djstest.pass('"Key that has never been added" was removed from the store');
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.contains("Key2", function (contained) {
                        djstest.assert(contained, "Key2 is present in the store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Remove Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeUpdateTest(mechanism) {
                var store = this.createStore("store8");

                var startKey = "Key1";
                var startValue = "start value";
                var updateKey = "Key2";
                var updatedValue = "updated value";

                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add(startKey, startValue, success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.add(updateKey, startValue, success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.update(updateKey, updatedValue, function (key, value) {
                        djstest.assertAreEqual(key, updateKey, "Updated keys match");
                        djstest.assertAreEqualDeep(value, updatedValue, "Updated values match");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.read(updateKey, function (key, value) {
                        djstest.assertAreEqual(key, updateKey, "Updated keys match after get");
                        djstest.assertAreEqualDeep(value, updatedValue, "Updated values match after get");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.read(startKey, function (key, value) {
                        djstest.assertAreEqual(key, startKey, "Non updated keys match after get");
                        djstest.assertAreEqualDeep(value, startValue, "Non updated values match after get");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Update Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeClearTest(mechanism) {
                var store = this.createStore("store9");
                var store2 = this.createStore("store9_1");

                var job = new djstest.Job();
                job.queue(function (success, fail) {
                    store.add("Key1", "value in store", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.add("Key2", "value in store", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.add("Key3", "value in store", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store2.add("Key1", "value in store2", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.clear(function () {
                        djstest.pass("Store was cleared");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.contains("Key1", function (contained) {
                        djstest.assert(!contained, "Key1 was removed from store");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store2.contains("Key1", function (contained) {
                        djstest.assert(contained, "Key1 still exists in store 2");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    store2.close();
                    testJobDone(succeeded);
                });
            }, "Store Clear Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeUpdateNonExistentTest(mechanism) {
                var store = this.createStore("store10");
                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add("key", "value", success, makeUnexpectedErrorHandler(fail));
                });

                job.queue(function (success, fail) {
                    store.update("badKey", "new value",
                        function () {
                            djstest.fail("Sucess handler called when not expected");
                            fail();
                        },
                        function (err) {
                            djstest.pass("Error callback called as expexted");
                            success();
                        });
                });

                job.queue(function (success, fail) {
                    store.update(["key", "badkey"], ["value", "badvalue"],
                        function () {
                            djstest.fail("Sucess handler called when not expected");
                            fail();
                        },
                        function (err) {
                            djstest.pass("Error callback called as expected");
                            success();
                        });
                });

                job.queue(function (success, fail) {
                    store.read("key", function (key, value) {
                        djstest.assertAreEqual(value, "value", "value was not changed");
                        success();
                    }, makeUnexpectedErrorHandler(fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Update Non-Existent Test with mechanism " + mechanism, mechanism);

            djstest.addTest(function storeUpdateArrayTest(mechanism) {
                var makeError = function (success, fail) {
                    return function (err) {
                        if (mechanism !== "indexeddb") {
                            djstest.pass("Error callback called as expected");
                            success();
                        } else {
                            djstest.fail(err.message);
                            fail();
                        }
                    };
                };

                var store = this.createStore("store11");
                var job = new djstest.Job();

                job.queue(function (success, fail) {
                    store.add(["key", "key2"], ["value1", "value2"], success, makeError(success, fail));
                });

                job.queue(function (success, fail) {
                    store.update(["key", "key2"], ["value1", "value4"], success, makeError(success, fail));
                });

                job.queue(function (success, fail) {
                    store.read(["key", "key2"], function (key, value) {
                        djstest.assertAreEqualDeep(value, ["value1", "value4"], "value was not changed");
                        success();
                    }, makeError(success, fail));
                });

                job.run(function (succeeded) {
                    store.close();
                    testJobDone(succeeded);
                });
            }, "Store Update Array Test with mechanism " + mechanism, mechanism);
        }
    }

    module("Unit");

    djstest.addTest(function CreateStoreTest() {
        var defaultExpected = canCreateDomStore() ? "dom" : "memory";
        var tests = [
            { mechanism: "dom", exception: !canCreateDomStore(), expected: "dom" },
            { mechanism: "memory", exception: false, expected: "memory" },
            { mechanism: "", exception: false, expected: defaultExpected },
            { mechanism: null, exception: false, expected: defaultExpected },
            { mechanism: "unknown", exception: true }
       ];

        var i, len;
        for (i = 0, len = tests.length; i < len; i++) {
            try {
                var test = tests[i];
                var store = odatajs.store.createStore("testStore" + i, tests[i].mechanism);

                if (!test.exception) {
                    djstest.assertAreEqual(store.mechanism, test.expected, "Created store of the expected mechanism");
                } else {
                    djstest.fail("Didn't get the expected exception");
                }
            }
            catch (e) {
                djstest.assert(test.exception, "Expected exception");
            }
        }
        djstest.done();
    });

    djstest.addTest(function CreateBestStoreTest() {
        var bestMechanism;

        for (var name in mechanismImplementations) {
            if (!bestMechanism && canCreateStore(name) && name !== "indexeddb") {
                bestMechanism = name;
            }
        }

        if (bestMechanism) {
            var tests = [
                "best",
                undefined
            ];

            for (var i in tests) {
                var store = odatajs.store.createStore("best store ever " + i, tests[i]);
                djstest.assertAreEqual(store.mechanism, bestMechanism, "Mechanisms match");
            }
        } else {
            djstest.pass("This browser doesn't support any of the implemented local storage mechanisms");
        }
        djstest.done();
    });

})(this);
