if (this.importScripts) {
    importScripts('../../../resources/js-test.js');
    importScripts('shared.js');
}

description("Test IndexedDB's IDBCursor.continue() behavior when called beyond normal scope.");

var date = new Date();

// we set this pretty high because we get different behavior depending
// if we're in a pre-fetched state or not
self.testLength = 25;

indexedDBTest(prepareDatabase);
function prepareDatabase()
{
    db = event.target.result;
    self.trans = evalAndLog("trans = event.target.transaction");
    shouldBeNonNull("trans");
    trans.onabort = unexpectedAbortCallback;

    self.objectStore = evalAndLog("db.createObjectStore('someObjectStore')");
    self.indexObject = evalAndLog("objectStore.createIndex('someIndex', 'x')");
    self.nextToAdd = 0;
    addData();
}

function addData()
{
    for (var i=0; i<self.testLength; i++) {
        evalAndLog("objectStore.add({'x': " + i + " }, " + i + ")");
    }
    evalAndLog("continueTest()");
}

function continueTest()
{
    debug("");
    debug("Checking objectStore");
    debug("====================");
    var request = evalAndLog("indexObject.openCursor(null, 'next')");
    evalAndLog("self.continueValue = 0");
    request.onsuccess = evalAndLogCallback("doubleContinueCallback()");
    request.onerror = unexpectedErrorCallback;
    self.stage = 0;
}

function doubleContinueCallback()
{
    evalAndLog("cursor = event.target.result");
    if (cursor) {
        debug("Checking value at " + self.continueValue);
        // data should be valid before calling continue()
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);

        // Data should not change during iteration, even if continue() is called and extra time.
        evalAndLog("cursor.continue()");
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);

        // Even if continue is called more than once, the value still shouldn't change.
        evalAndExpectException("cursor.continue()", "DOMException.INVALID_STATE_ERR");
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);
        evalAndLog("self.continueValue++;");
    } else {
        evalAndLog("continueIndexTest()");
    }
}

function continueIndexTest()
{
    debug("");
    debug("Checking index");
    debug("==============");
    var request = evalAndLog("indexObject.openCursor(null, 'next')");
    evalAndLog("self.continueValue = 0");
    request.onsuccess = doubleContinueIndexCallback;
    request.onerror = unexpectedErrorCallback;
    self.stage = 0;
}

function doubleContinueIndexCallback()
{
    evalAndLog("cursor = event.target.result");
    if (cursor) {
        debug("Checking value at " + self.continueValue);
        // data should be valid before calling continue()
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);

        // Data should not change during iteration, even if continue() is called and extra time.
        evalAndLog("cursor.continue()");
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);

        // Even if continue is called more than once, the value still shouldn't change.
        evalAndExpectException("cursor.continue()", "DOMException.INVALID_STATE_ERR");
        shouldBe("cursor.key", "" + self.continueValue);
        shouldBe("cursor.value.x", "" + self.continueValue);
        evalAndLog("self.continueValue++;");
    } else {
        evalAndLog("testModifyContinueOrder()");
    }

}

// Note: This mutates the data
function testModifyContinueOrder()
{
    debug("");
    debug("Checking modification");
    debug("=====================");
    var request = evalAndLog("indexObject.openCursor(null, 'next')");
    evalAndLog("self.continueValue = 0");
    request.onsuccess = modifyContinueOrderCallback;
    request.onerror = unexpectedErrorCallback;
    self.stage = 0;
}

function modifyContinueOrderCallback()
{
    cursor = evalAndLog("cursor = event.target.result");

    self.continueValue++;
    if (cursor) {
        debug("");
        debug("Index key is: " + cursor.key);
        debug("Primary key is: " + cursor.primaryKey);
        debug("Value.x is: " + cursor.value.x);
        debug("Continue value: " + self.continueValue);

        // we sprinkle these checks across the dataset, to sample
        // behavior against pre-fetching. Make sure to use prime
        // numbers for these checks to avoid overlap.
        if (self.continueValue % 2 == 0) {
            // it's ok to call update() and then continue..
            debug("New Index key for primary key " + cursor.primaryKey + " is " + (100 + self.continueValue));
            evalAndLog("cursor.update({ x: 100 + self.continueValue })");
            evalAndLog("cursor.continue()");
        } else if (self.continueValue % 3 == 0) {
            // it's ok to call delete() and then continue
            debug("Deleting primary key " + cursor.primaryKey + " which currently has Index key " + cursor.key);
            evalAndLog("cursor.delete()");
            evalAndLog("cursor.continue()");
        } else if (self.continueValue % 5 == 0) {
            // it's NOT ok to call continue and then update
            evalAndLog("cursor.continue()");
            debug("Expecting exception setting new Index key for primary key " + cursor.primaryKey + " to " + (100 + self.continueValue));
            evalAndExpectException("cursor.update({ x: 100 + self.continueValue})",
                                   "DOMException.INVALID_STATE_ERR");
        } else if (self.continueValue % 7 == 0) {
            // it's NOT ok to call continue and then delete
            evalAndLog("cursor.continue()");
            debug("Expecting exception deleting primary key " + cursor.primaryKey + " which currently has Index key " + cursor.key);
            evalAndExpectException("cursor.delete()",
                                   "DOMException.INVALID_STATE_ERR");
        } else {
            evalAndLog("cursor.continue()");
        }

    } else {
        finishJSTest();
    }
}
