﻿// Copyright (c) Microsoft Open Technologies, Inc.  All rights reserved.
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation 
// files (the "Software"), to deal  in the Software without restriction, including without limitation the rights  to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

(function (window, undefined) {
    var djstest = {};

    window.djstest = djstest;

    djstest.indexedDB = window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.indexedDB;

    djstest.cleanStoreOnIndexedDb = function (storeObjects, done) {
        /// <summary>Cleans all the test data saved in the IndexedDb database.</summary>
        /// <param name="storeNames" type="Array">Array of store objects with a property that is the name of the store</param>
        /// <param name="done" type="Function">Callback function</param>

        var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || {};

        var deleteObjectStores = function (db) {
            $.each(db.objectStoreNames, function (_, storeName) {
                db.deleteObjectStore(storeName);
            });
        };

        if (djstest.indexedDB) {
            var job = new djstest.Job();
            $.each(storeObjects, function (_, storeObject) {
                job.queue((function (storeObject) {
                    return function (success, fail) {
                        var dbname = "_datajs_" + storeObject.name;
                        var request = djstest.indexedDB.open(dbname);
                        request.onsuccess = function (event) {
                            var db = request.result;

                            if ("setVersion" in db) {
                                var versionRequest = db.setVersion("0.1");
                                versionRequest.onsuccess = function (event) {
                                    var transaction = versionRequest.transaction;
                                    transaction.oncomplete = function () {
                                        db.close();
                                        success();
                                    }
                                    deleteObjectStores(db);
                                };
                                versionRequest.onerror = function (e) {
                                    djstest.fail("Error on cleanup - code: " + e.code + " name: " + e.name + "message: " + message);
                                    fail();
                                };
                                return;
                            }

                            // new api cleanup
                            db.close();
                            var deleteRequest = djstest.indexedDB.deleteDatabase(dbname);
                            deleteRequest.onsuccess = function (event) {
                                djstest.log("djstest indexeddb cleanup - deleted database " + dbname);
                                success();
                            };
                            deleteRequest.onerror = function (e) {
                                djstest.fail("djstest indexeddb cleanup - error deleting database " + dbname);
                                fail();
                            };
                            djstest.log("djstest indexeddb cleanup - requested deletion of database " + dbname);
                        };

                        request.onerror = function (e) {
                            djstest.fail(e.code + ": " + e.message);
                        };
                    };
                })(storeObject));
            });
        }

        if (job) {
            job.run(function (succeeded) {
                if (!succeeded) {
                    djstest.fail("cleanup job failed");
                }
                done();
            });
        }
        else {
            done();
        }
    };

    djstest.Job = function () {
        /// <summary>Constructs a Job object that allows for enqueuing and synchronizing the execution of functions.</summary>
        /// <returns type="Object">Job object</returns>
        var currentTask = -1;
        var tasks = [];

        var failedTasks = 0;

        this.queue = function (fn) {
            /// <summary>Adds a function to the job queue regardless if the queue is already executing or not.</summary>
            /// <param name="fn" type="Function">Function to execute.</param>
            tasks.push(fn);
        };

        this.queueNext = function (fn) {
            /// <summary>Adds a function to the front of the job queue regardless if the queue is already executing or not.</summary>
            /// <param name="fn" type="Function">Function to execute.</param>
            if (currentTask < 0) {
                tasks.unshift(fn);
            } else {
                tasks.splice(currentTask + 1, 0, fn);
            }
        };

        this.run = function (done) {
            /// <summary>Starts the execution of this job.</summary>
            /// <param name="done" type="Function">Callback invoked when the job has finished executing all of its enqueued tasks.</param>
            /// <remarks>
            /// This method does nothing if called on a unit of work that is already executing.
            /// </remarks>

            if (currentTask >= 0) {
                return;
            }

            if (tasks.length === 0) {
                done(true);
                return;
            }

            var makeTaskDoneCallBack = function (failed) {
                return function () {
                    // Track the failed task and continue the execution of the job. 
                    if (failed) {
                        failedTasks++;
                    }
                    currentTask++;
                    if (currentTask === tasks.length) {
                        done(failedTasks === 0);
                    } else {
                        runNextTask();
                    }
                };
            };

            var runNextTask = function () {
                /// <summary>Executes the next function in the queue.</summary>
                defer(function () {
                    try {
                        tasks[currentTask](makeTaskDoneCallBack(false), makeTaskDoneCallBack(true));
                    } catch (e) {
                        makeTaskDoneCallBack(true)();
                    }
                });
            };

            currentTask = 0;
            runNextTask();
        };
    };

    var defer = function (fn) {
        /// <summary>Defers the execution of an arbitrary function that takes no parameters.</summary>
        /// <param name="fn" type="Function">Function to schedule for later execution.</param>
        setTimeout(fn, 0);
    }

    var exposeDateValues = function (data) {
        /// <summary>Exposes date values for Date objects to facilitate debugging</summary>
        /// <param name="data" type="Object">The object to operate on</param>
        if (typeof data === "object") {
            if (data instanceof Date) {
                data["__date__"] = data.toUTCString();
            }
            else {
                for (var prop in data) {
                    exposeDateValues(data[prop]);
                }
            }
        }

        return data;
    }

    var extractFunctionName = function (text) {
        /// <summary>Determines the name of a function.</summary>
        /// <param name="text" type="String">Function text.</param>
        /// <returns type="String">The name of the function from text if found; the original text otherwise.</returns>

        var index = text.indexOf("function ");
        if (index < 0) {
            return text;
        }

        var nameStart = index + "function ".length;
        var parensIndex = text.indexOf("(", nameStart);
        if (parensIndex < 0) {
            return text;
        }

        var result = text.substr(nameStart, parensIndex - nameStart);
        if (result.indexOf("test") === 0) {
            result = result.substr("test".length);
        }

        return result;
    };

    var removeMetadata = function (data) {
        /// <summary>Removes metadata annotations from the specified object.</summary>
        /// <param name="data">Object to remove metadata from; possibly null.</param>

        if (typeof data === "object" && data !== null) {
            delete data["__metadata"];
            for (prop in data) {
                removeMetadata(data[prop]);
            }
        }
    };

    djstest.addFullTest = function (disable, fn, name, arg, timeout) {
        /// <summary>Add the unit test cases</summary>
        /// <param name="disable">Indicate whether this test case should be disabled</param>
        if (disable != true) {
            djstest.addTest(fn, name, arg, timeout);
        }
    };


    djstest.addTest = function (fn, name, arg, timeout) {
        if (!name) {
            name = extractFunctionName(fn.toString());
        }

        test(name, function () {
            if (!timeout) {
                timeout = 20000;
            }

            QUnit.config.testTimeout = timeout;
            QUnit.stop();
            fn.call(this, arg);
        });
    };

    djstest.assert = function (test, message) {
        /// <summary>Asserts that a condition is true.</summary>
        /// <param name="test" type="Boolean">Condition to test.</param>
        /// <param name="message" type="String">Text message for condition being tested.</param>
        QUnit.ok(test, message);
    };

    djstest.assertAreEqual = function (actual, expected, message) {
        /// <summary>Asserts that the values of the expected and actualobjects are equal.</summary>
        QUnit.equal(actual, expected, message);
    };

    djstest.assertAreEqualDeep = function (actual, expected, message) {
        /// <summary>Asserts that the actual and expected objects are the same.</summary>
        QUnit.deepEqual(exposeDateValues(actual), exposeDateValues(expected), message);
    };

    djstest.assertWithoutMetadata = function (actual, expected, message) {
        removeMetadata(actual)
        removeMetadata(expected);
        djstest.assertAreEqualDeep(actual, expected, message);
    };

    djstest.asyncDo = function (asyncActions, done) {
        /// <summary>Calls each async action in asyncActions, passing each action a function which keeps a count and
        /// calls the passed done function when all async actions complete.</summary>
        /// <param name="asyncActions" type="Array">Array of asynchronous actions to be executed, 
        /// each taking a single parameter - the callback function to call when the action is done.</param>
        /// <param name="done" type="Function">Function to be executed in the last async action to complete.</param>
        var count = 0;
        var doneOne = function () {
            count++;
            if (count >= asyncActions.length) {
                done();
            }
        };

        if (asyncActions.length > 0) {
            $.each(asyncActions, function (_, asyncAction) {
                asyncAction(doneOne);
            });
        } else {
            done();
        }
    }

    djstest.clone = function (object) {
        /// <summary>Makes a deep copy of an object.</summary>
        return $.extend(true, {}, object);
    };

    djstest.destroyCacheAndDone = function (cache) {
        /// <summary>Destroys the cache and then completes the test</summary>
        /// <param name="cache">The cache to destroy</param>
        cache.clear().then(function () {
            djstest.done();
        }, function (err) {
            djstest.fail("Failed to destroy cache: " + djstest.toString(err));
            djstest.done();
        });
    };

    djstest.done = function () {
        /// <summary>Indicates that the currently running test has finished.</summary>
        QUnit.start();
    };

    djstest.expectException = function (testFunction, message) {
        /// <summary>Test passes if and only if an exception is thrown.</summary>
        try {
            testFunction();
            djstest.fail("Expected exception but function succeeded: " + " " + message);
        }
        catch (e) {
            // Swallow exception.
            djstest.pass("Thrown exception expected");
        }
    };

    djstest.assertsExpected = function (asserts) {
        /// <summary>Indicates the expected number of asserts, fails test if number is not met.</summary>
        /// <param name="asserts" type="Number">Number of asserts expected in test.</param>
        expect(asserts);
    }

    djstest.fail = function (message) {
        /// <summary>Marks the current test as failed.</summary>
        /// <param name="message" type="String">Failure message.</param>
        QUnit.ok(false, message);
    };

    djstest.failAndDoneCallback = function (message, cleanupCallback) {
        /// <summary>Returns a function that when invoked will fail this test and be done with it.</summary>
        /// <param name="message" type="String">Failure message.</param>
        /// <param name="cleanupCallback" type="Function" optional="true">Optional cleanup function in case of failure.</param>
        /// <returns type="Function">A new function.</returns>

        return function (err) {
            message = "" + message + (err) ? window.JSON.stringify(err) : "";
            djstest.fail(message);
            if (cleanupCallback) {
                try {
                    cleanupCallback();
                } catch (e) {
                    djstest.fail("error during cleanupCallback: " + window.JSON.stringify(e));
                }
            }

            djstest.done();
        };
    };

    djstest.log = function (message) {
        /// <summary>Logs a test message.</summary>
        /// <param name="message" type="String">Test message.</param>
        var context = { result: true, actual: true, expected: true, message: message };
        QUnit.log(context);
    };

    djstest.pass = function (message) {
        /// <summary>Marks the current test as failed.</summary>
        /// <param name="message" type="String">Failure message.</param>
        QUnit.ok(true, message);
    };

    djstest.toString = function (obj) {
        /// <summary>Dumps the object as a string</summary>
        /// <param name="obj" type="Object">Object to dump</param>
        return QUnit.jsDump.parse(obj);
    };

    djstest.wait = function (fn) {
        /// <summary>Executes the function, pausing test execution until the callback is called</summary>
        /// <param name="fn" type="Function">Function to execute; takes one parameter which is the callback</param>
        /// <remarks>This function is typically used in asynchronous setup/teardown methods</remarks>
        QUnit.stop();
        fn(function () {
            QUnit.start();
        });
    };

    // Disable caching to ensure that every test-related AJAX request is actually being sent,
    // and set up a default error handler
    $.ajaxSetup({
        cache: false,
        error: function (jqXHR, textStatus, errorThrown) {
            // Work around bug in IE-Mobile on Windows Phone 7
            if (jqXHR.status !== 1223) {
                var err = {
                    status: jqXHR.status,
                    statusText: jqXHR.statusText,
                    responseText: jqXHR.responseText
                };
                djstest.fail("AJAX request failed with: " + djstest.toString(err));
            }
            djstest.done();
        }
    });
})(window);