﻿// 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.

// odata-json.js

(function (window, undefined) {

    var datajs = window.datajs || {};
    var odata = window.OData || {};

    // Imports 

    var defined = datajs.defined;
    var extend = datajs.extend;
    var isArray = datajs.isArray;
    var isDate = datajs.isDate;
    var normalizeURI = datajs.normalizeURI;
    var parseInt10 = datajs.parseInt10;

    var contentType = odata.contentType;
    var jsonLightReadPayload = odata.jsonLightReadPayload;
    var formatDateTimeOffset = odata.formatDateTimeOffset;
    var formatDuration = odata.formatDuration;
    var formatJsonLight = odata.formatJsonLight;
    var formatNumberWidth = odata.formatNumberWidth;
    var getCanonicalTimezone = odata.getCanonicalTimezone;
    var handler = odata.handler;
    var isComplex = odata.isComplex;
    var lookupComplexType = odata.lookupComplexType;
    var lookupEntityType = odata.lookupEntityType;
    var MAX_DATA_SERVICE_VERSION = odata.MAX_DATA_SERVICE_VERSION;
    var maxVersion = odata.maxVersion;
    var parseDateTime = odata.parseDateTime;
    var parseDuration = odata.parseDuration;
    var parseTimezone = odata.parseTimezone;
    var payloadTypeOf = odata.payloadTypeOf;
    var traverse = odata.traverse;
    var formatJsonLightRequestPayload = odata.formatJsonLightRequestPayload;

    // CONTENT START

    var jsonMediaType = "application/json";
    var jsonContentType = contentType(jsonMediaType);

    var jsonReadAdvertisedActionsOrFunctions = function (value) {
        /// <summary>Reads and object containing action or function metadata and maps them into a single array of objects.</summary>
        /// <param name="value" type="Object">Object containing action or function metadata.</param>
        /// <returns type="Array">Array of objects containing metadata for the actions or functions specified in value.</returns>

        var result = [];
        for (var name in value) {
            var i, len;
            for (i = 0, len = value[name].length; i < len; i++) {
                result.push(extend({ metadata: name }, value[name][i]));
            }
        }
        return result;
    };

    var jsonApplyMetadata = function (value, metadata, dateParser, recognizeDates) {
        /// <summary>Applies metadata coming from both the payload and the metadata object to the value.</summary>
        /// <param name="value" type="Object">Data on which the metada is going to be applied.</param>
        /// <param name="metadata">Metadata store; one of edmx, schema, or an array of any of them.</param>
        /// <param name="dateParser" type="function">Function used for parsing datetime values.</param>
        /// <param name="recognizeDates" type="Boolean">
        ///     True if strings formatted as datetime values should be treated as datetime values. False otherwise.
        /// </param>
        /// <returns type="Object">Transformed data.</returns>

        if (value && typeof value === "object") {
            var dataTypeName;
            var valueMetadata = value.__metadata;

            if (valueMetadata) {
                if (valueMetadata.actions) {
                    valueMetadata.actions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.actions);
                }
                if (valueMetadata.functions) {
                    valueMetadata.functions = jsonReadAdvertisedActionsOrFunctions(valueMetadata.functions);
                }
                dataTypeName = valueMetadata && valueMetadata.type;
            }

            var dataType = lookupEntityType(dataTypeName, metadata) || lookupComplexType(dataTypeName, metadata);
            var propertyValue;
            if (dataType) {
                var properties = dataType.property;
                if (properties) {
                    var i, len;
                    for (i = 0, len = properties.length; i < len; i++) {
                        var property = properties[i];
                        var propertyName = property.name;
                        propertyValue = value[propertyName];

                        if (property.type === "Edm.DateTime" || property.type === "Edm.DateTimeOffset") {
                            if (propertyValue) {
                                propertyValue = dateParser(propertyValue);
                                if (!propertyValue) {
                                    throw { message: "Invalid date/time value" };
                                }
                                value[propertyName] = propertyValue;
                            }
                        } else if (property.type === "Edm.Time") {
                            value[propertyName] = parseDuration(propertyValue);
                        }
                    }
                }
            } else if (recognizeDates) {
                for (var name in value) {
                    propertyValue = value[name];
                    if (typeof propertyValue === "string") {
                        value[name] = dateParser(propertyValue) || propertyValue;
                    }
                }
            }
        }
        return value;
    };

    var isJsonLight = function (contentType) {
        /// <summary>Tests where the content type indicates a json light payload.</summary>
        /// <param name="contentType">Object with media type and properties dictionary.</param>
        /// <returns type="Boolean">True is the content type indicates a json light payload. False otherwise.</returns>

        if (contentType) {
            var odata = contentType.properties["odata.metadata"];
            return odata === "none" || odata === "minimal" || odata === "full";
        }

        return false;
    };

    var normalizeServiceDocument = function (data, baseURI) {
        /// <summary>Normalizes a JSON service document to look like an ATOM service document.</summary>
        /// <param name="data" type="Object">Object representation of service documents as deserialized.</param>
        /// <param name="baseURI" type="String">Base URI to resolve relative URIs.</param>
        /// <returns type="Object">An object representation of the service document.</returns>
        var workspace = { collections: [] };

        var i, len;
        for (i = 0, len = data.EntitySets.length; i < len; i++) {
            var title = data.EntitySets[i];
            var collection = {
                title: title,
                href: normalizeURI(title, baseURI)
            };

            workspace.collections.push(collection);
        }

        return { workspaces: [workspace] };
    };

    // The regular expression corresponds to something like this:
    // /Date(123+60)/
    //
    // This first number is date ticks, the + may be a - and is optional,
    // with the second number indicating a timezone offset in minutes.
    //
    // On the wire, the leading and trailing forward slashes are
    // escaped without being required to so the chance of collisions is reduced;
    // however, by the time we see the objects, the characters already
    // look like regular forward slashes.
    var jsonDateRE = /^\/Date\((-?\d+)(\+|-)?(\d+)?\)\/$/;

    var minutesToOffset = function (minutes) {
        /// <summary>Formats the given minutes into (+/-)hh:mm format.</summary>
        /// <param name="minutes" type="Number">Number of minutes to format.</param>
        /// <returns type="String">The minutes in (+/-)hh:mm format.</returns>

        var sign;
        if (minutes < 0) {
            sign = "-";
            minutes = -minutes;
        } else {
            sign = "+";
        }

        var hours = Math.floor(minutes / 60);
        minutes = minutes - (60 * hours);

        return sign + formatNumberWidth(hours, 2) + ":" + formatNumberWidth(minutes, 2);
    };

    var parseJsonDateString = function (value) {
        /// <summary>Parses the JSON Date representation into a Date object.</summary>
        /// <param name="value" type="String">String value.</param>
        /// <returns type="Date">A Date object if the value matches one; falsy otherwise.</returns>

        var arr = value && jsonDateRE.exec(value);
        if (arr) {
            // 0 - complete results; 1 - ticks; 2 - sign; 3 - minutes
            var result = new Date(parseInt10(arr[1]));
            if (arr[2]) {
                var mins = parseInt10(arr[3]);
                if (arr[2] === "-") {
                    mins = -mins;
                }

                // The offset is reversed to get back the UTC date, which is
                // what the API will eventually have.
                var current = result.getUTCMinutes();
                result.setUTCMinutes(current - mins);
                result.__edmType = "Edm.DateTimeOffset";
                result.__offset = minutesToOffset(mins);
            }
            if (!isNaN(result.valueOf())) {
                return result;
            }
        }

        // Allow undefined to be returned.
    };

    // Some JSON implementations cannot produce the character sequence \/
    // which is needed to format DateTime and DateTimeOffset into the
    // JSON string representation defined by the OData protocol.
    // See the history of this file for a candidate implementation of
    // a 'formatJsonDateString' function.

    var jsonParser = function (handler, text, context) {
        /// <summary>Parses a JSON OData payload.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="text">Payload text (this parser also handles pre-parsed objects).</param>
        /// <param name="context" type="Object">Object with parsing context.</param>
        /// <returns>An object representation of the OData payload.</returns>

        var dataServiceVersion = context.dataServiceVersion;
        var json = (typeof text === "string") ? window.JSON.parse(text) : text;

        if ((maxVersion("4.0", dataServiceVersion) === dataServiceVersion)) {
            return json;
        }

        return undefined;
    };

    var jsonToString = function (data) {
        /// <summary>Converts the data into a JSON string.</summary>
        /// <param name="data">Data to serialize.</param>
        /// <returns type="String">The JSON string representation of data.</returns>

        var result; // = undefined;
        // Save the current date.toJSON function
        var dateToJSON = Date.prototype.toJSON;
        try {
            // Set our own date.toJSON function
            Date.prototype.toJSON = function () {
                return formatDateTimeOffset(this);
            };
            result = window.JSON.stringify(data, jsonReplacer);
        } finally {
            // Restore the original toJSON function
            Date.prototype.toJSON = dateToJSON;
        }
        return result;
    };

    var jsonSerializer = function (handler, data, context) {
        /// <summary>Serializes the data by returning its string representation.</summary>
        /// <param name="handler">This handler.</param>
        /// <param name="data">Data to serialize.</param>
        /// <param name="context" type="Object">Object with serialization context.</param>
        /// <returns type="String">The string representation of data.</returns>

        var dataServiceVersion = context.dataServiceVersion || "4.0";
        var cType = context.contentType = context.contentType || jsonContentType;

        if (cType && cType.mediaType === jsonContentType.mediaType) {
            context.dataServiceVersion = maxVersion(dataServiceVersion, "4.0");
            var newdata = formatJsonLightRequestPayload(data);
            if (newdata) {
                return window.JSON.stringify(newdata);
            }
        }

        return undefined;
    };

    var jsonReplacer = function (_, value) {
        /// <summary>JSON replacer function for converting a value to its JSON representation.</summary>
        /// <param value type="Object">Value to convert.</param>
        /// <returns type="String">JSON representation of the input value.</returns>
        /// <remarks>
        ///   This method is used during JSON serialization and invoked only by the JSON.stringify function.
        ///   It should never be called directly.
        /// </remarks>

        if (value && value.__edmType === "Edm.Time") {
            return formatDuration(value);
        } else {
            return value;
        }
    };

    var jsonNormalizeData = function (data, baseURI) {
        /// <summary>
        /// Normalizes the specified data into an intermediate representation.
        /// like the latest supported version.
        /// </summary>
        /// <param name="data" optional="false">Data to update.</param>
        /// <param name="baseURI" optional="false">URI to use as the base for normalizing references.</param>

        var isSvcDoc = isComplex(data) && !data.__metadata && isArray(data.EntitySets);
        return isSvcDoc ? normalizeServiceDocument(data, baseURI) : data;
    };

    var jsonHandler = handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
    jsonHandler.recognizeDates = false;

    odata.jsonHandler = jsonHandler;



    // DATAJS INTERNAL START
    odata.jsonParser = jsonParser;
    odata.jsonSerializer = jsonSerializer;
    odata.jsonNormalizeData = jsonNormalizeData;
    odata.normalizeServiceDocument = normalizeServiceDocument;
    odata.parseJsonDateString = parseJsonDateString;
    // DATAJS INTERNAL END

    // CONTENT END
})(this);




