﻿// Copyright (c) Microsoft.  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.

// CacheOracle.js
// This object verifies the operation of the cache.
// Internally it maintains a simple model of the cache implemented using a lookup array of the expected cached pages.

(function (window, undefined) {

    var CacheOracle = function (baseUri, pageSize, total) {
        /// <summary>Creates a new CacheOracle</summary>
        /// <param name="baseUri" type="String">The base URI of the collection</param>
        /// <param name="pageSize" type="Integer">The page size used in the cache</param>
        /// <param name="total" type="Integer">The total number of items in the collection</param>
        this.baseUri = baseUri;
        this.pageSize = pageSize;
        this.total = total;

        this.cachedPages = [];
    };

    CacheOracle.mechanisms = {
        memory: "memory",
        indexeddb: "indexeddb",
        dom: "dom",
        best: "best"
    };

    CacheOracle.isMechanismAvailable = function (mechanism) {
        /// <summary>Determines if the specified local storage mechanism is available</summary>
        /// <param name="mechanism">The name of the mechanism</param>
        /// <returns>Whether the mechanism is available</returns>
        switch (mechanism) {
            case CacheOracle.mechanisms.indexeddb:
                if (window.mozIndexedDB) {
                    return true;
                }
                else {
                    return false;
                }
                break;
            case CacheOracle.mechanisms.dom:
                if (window.localStorage) {
                    return true;
                }
                else {
                    return false;
                }
                break;
            case CacheOracle.mechanisms.memory:
            case CacheOracle.mechanisms.best:
            case undefined:
                return true;
            default:
                return false;
        }
    }

    CacheOracle.prototype.clear = function () {
        /// <summary>Clears the cache in the oracle</summary>
        this.cachedPages = [];
    }

    CacheOracle.prototype.verifyRequests = function (requests, responses, index, count, description) {
        /// <summary>Verifies the HTTP requests for a single data request, and updates the oracle with cached pages</summary>
        /// <param name="requests" type="Array">The sequence of request objects (from OData.defaultHttpClient)</param>
        /// <param name="responses" type="Array">The sequence of response objects (from OData.defaultHttpClient)</param>
        /// <param name="index" type="Integer">The starting index of the read</param>
        /// <param name="count" type="Integer">The count of items in the read</param>
        /// <param name="description" type="String">The description of the requests being verified</param>
        var that = this;

        var pageIndex = function (index) {
            /// <summary>Returns the page index that the given item index belongs to</summary>
            /// <param name="index" type="Integer">The item index</param>
            /// <returns>The page index</returns>
            return Math.floor(index / that.pageSize);
        }

        var minPage = pageIndex(index);
        var maxPage = Math.min(pageIndex(index + count - 1), pageIndex(that.total));

        // Workaround for Bug 2055: Calling readRange with count = 0 still fires a single HTTP request
        maxPage = Math.max(minPage, maxPage);

        var expectedUris = [];
        var responseIndex = 0;
        for (var page = minPage; page <= maxPage; page++) {
            if (!this.cachedPages[page]) {
                expectedUris.push(that.baseUri + "?$skip=" + page * that.pageSize + "&$top=" + (that.pageSize));

                // Handle server paging skipToken requests
                while (responses[responseIndex] && responses[responseIndex].data && responses[responseIndex].data.__next) {
                    expectedUris.push(responses[responseIndex].data.__next);
                    responseIndex++;
                }

                responseIndex++;
                this.cachedPages[page] = true;
            }
        }

        var actualUris = $.map(requests, function (r) { return r.requestUri; });
        djstest.assertAreEqualDeep(actualUris, expectedUris, description);
    };

    window.CacheOracle = CacheOracle;

})(this);