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

/* {
    oldname:'odata-json.js',
    updated:'20140514 12:59'
}*/

var utils    = require('./../datajs.js').utils;
var oDataUtils    = require('./utils.js');
var oDataHandler    = require('./handler.js');

var odataNs = "odata";
var odataAnnotationPrefix = odataNs + ".";
var contextUrlAnnotation = "@" + odataAnnotationPrefix + "context";

var assigned = utils.assigned;
var defined = utils.defined;
var extend = utils.extend;
var isArray = utils.isArray;
var isDate = utils.isDate;
var isObject = utils.isObject;
var normalizeURI = utils.normalizeURI;
var parseInt10 = utils.parseInt10;

var contentType = oDataUtils.contentType;
var formatDateTimeOffset = oDataUtils.formatDateTimeOffset;
var formatDuration = oDataUtils.formatDuration;
var formatJsonLight = oDataUtils.formatJsonLight;
var formatNumberWidth = oDataUtils.formatNumberWidth;
var getCanonicalTimezone = oDataUtils.getCanonicalTimezone;
var handler = oDataUtils.handler;
var isComplex = oDataUtils.isComplex;
var isCollectionType = oDataUtils.isCollectionType;
var lookupComplexType = oDataUtils.lookupComplexType;
var lookupEntityType = oDataUtils.lookupEntityType;
var lookupSingleton = oDataUtils.lookupSingleton;
var lookupEntitySet = oDataUtils.lookupEntitySet;
var lookupDefaultEntityContainer = oDataUtils.lookupDefaultEntityContainer;
var lookupProperty = oDataUtils.lookupProperty;
var MAX_DATA_SERVICE_VERSION = oDataUtils.MAX_DATA_SERVICE_VERSION;
var maxVersion = oDataUtils.maxVersion;
var parseDateTime = oDataUtils.parseDateTime;
var parseDuration = oDataUtils.parseDuration;
var parseTimezone = oDataUtils.parseTimezone;
var payloadTypeOf = oDataUtils.payloadTypeOf;
var traverse = oDataUtils.traverse;

// CONTENT START

var PAYLOADTYPE_FEED = "f";
var PAYLOADTYPE_ENTRY = "e";
var PAYLOADTYPE_PROPERTY = "p";
var PAYLOADTYPE_COLLECTION = "c";
var PAYLOADTYPE_ENUMERATION_PROPERTY = "enum";
var PAYLOADTYPE_SVCDOC = "s";
var PAYLOADTYPE_ENTITY_REF_LINK = "erl";
var PAYLOADTYPE_ENTITY_REF_LINKS = "erls";

var PAYLOADTYPE_VALUE = "v";

var PAYLOADTYPE_DELTA = "d";
var DELTATYPE_FEED = "f";
var DELTATYPE_DELETED_ENTRY = "de";
var DELTATYPE_LINK = "l";
var DELTATYPE_DELETED_LINK = "dl";

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


// 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 recognizeDates = defined(context.recognizeDates, handler.recognizeDates);
    var inferJsonLightFeedAsObject = defined(context.inferJsonLightFeedAsObject, handler.inferJsonLightFeedAsObject);
    var model = context.metadata;
    var dataServiceVersion = context.dataServiceVersion;
    var json = (typeof text === "string") ? JSON.parse(text) : text;
    var metadataMap = { none : 0, minimal : 1, full : 2, all : 3 };

    var payloadFormat = 1;//minmal
    try {
        payloadFormat = metadataMap[context.contentType.properties["odata.metadata"]];//TODO convert to lower before comparism
    } catch(err) {
        payloadFormat = 1;
    }
    payloadFormat = (payloadFormat === undefined) ? 1 : payloadFormat;

    var demandedFormat = 1;//minmal
    try {
        demandedFormat = metadataMap[context.extendMetadataToLevel]; //TODO convert to lower before comparism
    } catch(err) {
        demandedFormat = 1;
    }
    demandedFormat = (demandedFormat === undefined) ? 1 : demandedFormat;

    if ( payloadFormat >= demandedFormat) {
        //there is no need to add additional metadata
        if (recognizeDates) {
            if (payloadFormat === 0) {
                //error no typeinformation in payload, conversion of dates not possible
            } else if (payloadFormat === 1) { //minimal
                //TODO use metadata in context to determine which properties need to be converted
            } else {
                return convertPrimitivetypesOnMetadataFull(json); //should be fast    
            }
        } else {
            return json;
        }
    } else {
        if (payloadFormat === 2) { 
            //demandedFormat is all
            //metaData=full, no metadata in context required
            //insert the missing type information for strings, bool, etc.
            //guess types for nummber as defined in the odata-json-format-v4.0.doc specification
            return extendMetadataFromPayload(json,context,recognizeDates);
        } else if (payloadFormat === 1) { //minmal
            if (!utils.isArray(model)) { // array was default for model in datajsV3 3.0 
                //TODO use metadata in context to determine which properties need to be converted
                // and extend the metadata
                return extendMetadataFromContext(json,context,model,demandedFormat, recognizeDates);
            } else {
                //error metadata in context required, TODO: throw a to be defined exception
            }
        } else {
            // the payload contains no context url only guessing possible
            return json;
        }
    }
};

var extendMetadataFromContext = function(json,context, model,demandedFormat,recognizeDates) {
    return jsonLightReadPayload(json, model, demandedFormat,recognizeDates, false, context.contentType.properties['odata.metadata']);
};

var convertPrimitivetypesOnMetadataFull = function(data) {
    /// <summary>Converts some primitive data types in payload</summary>
    /// <param name="data">Date which will be extendet</param>
    /// <returns>An object representation of the OData payload.</returns>

    if ( utils.isObject(data) ) {
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                if (key.indexOf('@') === -1) {
                    if (utils.isArray(data[key])) {
                        for ( var i = 0; i < data[key].length; ++i) {
                            convertPrimitivetypesOnMetadataFull(data[key][i]);
                        }
                    } else if (utils.isObject(data[key])) {
                        if (data[key] !== null) {
                            convertPrimitivetypesOnMetadataFull(data[key]);
                        }
                    } else {
                        var type = data[key+'@odata.type'];
                        if ( type === undefined ) {
                            var typeFromObject = typeof data[key];
                            //TODO check the datatype                             
                        } else if ( type === '#DateTimeOffset' ) {
                           data[key] = oDataUtils.parseDateTimeOffset(data[key],true);
                        } else if ( type === '#DateTime' ) {
                           data[key] = oDataUtils.parseDateTimeOffset(data[key],true);
                        }
                        //TODO handle more types there 
                    }
                }
            }
        }
    }
    return data;
};


var addType = function(data, name, value ) {
    var fullName = name+'@odata.type';

    if ( data[fullName] === undefined) {
        data[fullName] = value;
    }
};

var extendMetadataFromPayload = function(data,context,recognizeDates) {
    /// <summary>Adds typeinformation for String, Boolean and numerical EDM-types. 
    /// The type is determined from the odata-json-format-v4.0.doc specification
    ///</summary>
    /// <param name="data">Date which will be extendet</param>
    /// <param name="context" type="Object">Object with parsing context.</param>
    /// <param name="recognizeDates" type="Boolean">
    ///     True if strings formatted as datetime values should be treated as datetime values. False otherwise.
    /// </param>
    /// <returns>An object representation of the OData payload.</returns>

    if ( utils.isObject(data) ) {
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                if (key.indexOf('@') === -1) {
                    if (utils.isArray(data[key])) {
                        for ( var i = 0; i < data[key].length; ++i) {
                            extendMetadataFromPayload(data[key][i], context, recognizeDates);
                        }
                    } else if (utils.isObject(data[key])) {
                        if (data[key] !== null) {
                            extendMetadataFromPayload(data[key],context, recognizeDates);
                        }
                    } else {
                        if (recognizeDates) {
                            var type = data[key+'@odata.type'];
                            if ( type === undefined ) {
                                var typeFromObject = typeof data[key];
                                //TODO check the datatype                             
                            } else if ( type === '#DateTimeOffset' ) {
                               data[key] = oDataUtils.parseDateTimeOffset(data[key],true);
                            } else if ( type === '#DateTime' ) {
                               data[key] = oDataUtils.parseDateTimeOffset(data[key],true);
                            }
                            //TODO handle more types there 
                        }
                        var typeFromObject = typeof data[key];
                        if ( typeFromObject === 'string' ) {
                           addType(data,key,'#String');
                        } else if (typeFromObject ==='boolean') {
                            addType(data,key,'#Bool');
                        } else if (typeFromObject ==='number') {
                            if ( data[key] % 1 === 0 ) { // has fraction 
                                addType(data,key,'#Integer');// the biggst integer
                            } else {
                                addType(data,key,'#Decimal');// the biggst float single,doulbe,decimal
                            }
                        }
                    }
                }
            }
        }
    }
    return data;
};



/*
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 formatDateTimeOffsetJSON(this);
        };
        result = JSON.stringify(data, jsonReplacer);
        result = result.replace(/\/Date\(([0-9.+-]+)\)\//g, "\\/Date($1)\\/");
    } 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 JSON.stringify(newdata);
        }
    }

    return undefined;
};

var formatJsonLightRequestPayload = function (data) {
    if (!data) {
        return data;
    }

    if (isPrimitive(data)) {
        return data;
    }

    if (isArray(data)) {
        var newArrayData = [];
        var i, len;
        for (i = 0, len = data.length; i < len; i++) {
            newArrayData[i] = formatJsonLightRequestPayload(data[i]);
        }

        return newArrayData;
    }

    var newdata = {};
    for (var property in data) {
        if (isJsonLightSerializableProperty(property)) {
            newdata[property] = formatJsonLightRequestPayload(data[property]);
        }
    }

    return newdata;
};
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 jsonLightMakePayloadInfo = function (kind, type) {
    /// <summary>Creates an object containing information for the json light payload.</summary>
    /// <param name="kind" type="String">JSON light payload kind, one of the PAYLOADTYPE_XXX constant values.</param>
    /// <param name="typeName" type="String">Type name of the JSON light payload.</param>
    /// <returns type="Object">Object with kind and type fields.</returns>

    /// <field name="kind" type="String">Kind of the JSON light payload. One of the PAYLOADTYPE_XXX constant values.</field>
    /// <field name="type" type="String">Data type of the JSON light payload.</field>

    return { kind: kind, type: type || null };
};

/// <summary>Creates an object containing information for the context</summary>
/// ...
/// <returns type="Object">Object with type information
/// attribute detectedPayloadKind(optional): see constants starting with PAYLOADTYPE_
/// attribute deltaKind(optional): deltainformation, one of the following valus DELTATYPE_FEED | DELTATYPE_DELETED_ENTRY | DELTATYPE_LINK | DELTATYPE_DELETED_LINK
/// attribute typeName(optional): name of the type
/// attribute type(optional): object containing type information for entity- and complex-types ( null if a typeName is a primitive)
///  </returns>
var parseContextUriFragment = function( fragments, model ) {
    var ret = {};

    
    if (fragments.indexOf('/') === -1 ) {
        if (fragments.length === 0) {
            // Capter 10.1
            ret.detectedPayloadKind = PAYLOADTYPE_SVCDOC;
            return ret;
        } else if (fragments === 'Edm.Null') {
            // Capter 10.15
            ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
            ret.isNullProperty = true;
            return ret;
        } else if (fragments === 'Collection($ref)') {
            // Capter 10.11
            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINKS;
            return ret;
        } else if (fragments === '$ref') {
            // Capter 10.12
            ret.detectedPayloadKind = PAYLOADTYPE_ENTITY_REF_LINK;
            return ret;
        } else {
            //TODO check for navigation resource
        }
    } 

    ret.type = undefined;
    ret.typeName = undefined;

    var fragmentParts = fragments.split("/");
    
    for(var i = 0; i < fragmentParts.length; ++i) {
        var fragment = fragmentParts[i];
        if (ret.typeName === undefined) {
            //preparation
            if ( fragment.indexOf('(') !== -1 ) {
                //remove the query function, cut fragment to matching '('
                var index = fragment.length - 2 ;
                for ( var rCount = 1; rCount > 0 && index > 0; --index) {
                    if ( fragment.charAt(index)=='(') {
                        rCount --;
                    } else if ( fragment.charAt(index)==')') {
                        rCount ++;    
                    }
                }

                if (index === 0) {
                    //TODO throw error
                }

                //remove the projected entity from the fragment; TODO decide if we want to store the projected entity 
                var inPharenthesis = fragment.substring(index+2,fragment.length - 1);
                fragment = fragment.substring(0,index+1);

                if (utils.startsWith(fragment, 'Collection')) {
                    ret.detectedPayloadKind = PAYLOADTYPE_COLLECTION;
                    // Capter 10.14
                    ret.typeName = inPharenthesis;

                    var type = lookupEntityType(ret.typeName, model);
                    if ( type !== null) {
                        ret.type = type;
                        continue;
                    }
                    type = lookupComplexType(ret.typeName, model);
                    if ( type !== null) {
                        ret.type = type;
                        continue;
                    }

                    ret.type = null;//in case of #Collection(Edm.String) only lastTypeName is filled
                    continue;
                } else {
                    // projection: Capter 10.7, 10.8 and 10.9
                    ret.projection = inPharenthesis;
                }
            }

            var container = lookupDefaultEntityContainer(model);

            //check for entity
            var entitySet = lookupEntitySet(container.entitySet, fragment);
            if ( entitySet !== null) {
                ret.typeName = entitySet.entityType;
                ret.type = lookupEntityType( ret.typeName, model);
                ret.name = fragment;
                ret.detectedPayloadKind = PAYLOADTYPE_FEED;
                // Capter 10.2
                continue;
            }

            //check for singleton
            var singleton = lookupSingleton(container.singleton, fragment);
            if ( singleton !== null) {
                ret.typeName = singleton.entityType;
                ret.type = lookupEntityType( ret.typeName, model);
                ret.name = fragment;
                ret.detectedPayloadKind =  PAYLOADTYPE_ENTRY;
                // Capter 10.4
                continue;
            }

            if (jsonLightIsPrimitiveType(fragment)) {
                ret.typeName = fragment;
                ret.type = null;
                ret.detectedPayloadKind = PAYLOADTYPE_VALUE;
                continue;
            }

            //TODO throw ERROR
        } else {
            //check for $entity
            if (utils.endsWith(fragment, '$entity') && (ret.detectedPayloadKind === PAYLOADTYPE_FEED)) {
                //TODO ret.name = fragment;
                ret.detectedPayloadKind = PAYLOADTYPE_ENTRY;
                // Capter 10.3 and 10.6
                continue;
            } 

            //check for derived types
            if (fragment.indexOf('.') !== -1) {
                // Capter 10.6
                ret.typeName = fragment;
                var type = lookupEntityType(ret.typeName, model);
                if ( type !== null) {
                    ret.type = type;
                    continue;
                }
                type = lookupComplexType(ret.typeName, model);
                if ( type !== null) {
                    ret.type = type;
                    continue;
                }

                //TODO throw ERROR invalid type
            }

            //check for property value
            if ( ret.detectedPayloadKind === PAYLOADTYPE_FEED || ret.detectedPayloadKind === PAYLOADTYPE_ENTRY) {
                var property = lookupProperty(ret.type.property, fragment);
                if (property !== null) {
                    ret.typeName = property.type;
                    ret.type = lookupComplexType(ret.typeName, model);
                    ret.name = fragment;
                    ret.detectedPayloadKind = PAYLOADTYPE_PROPERTY;
                    // Capter 10.15
                }
                continue;
            }

            if (fragment === '$delta') {
                ret.deltaKind = DELTATYPE_FEED;
                continue;
            } else if (utils.endsWith(fragment, '/$deletedEntity')) {
                ret.deltaKind = DELTATYPE_DELETED_ENTRY;
                continue;
            } else if (utils.endsWith(fragment, '/$link')) {
                ret.deltaKind = DELTATYPE_LINK;
                continue;
            } else if (utils.endsWith(fragment, '/$deletedLink')) {
                ret.deltaKind = DELTATYPE_DELETED_LINK;
                continue;
            }
            //TODO throw ERROr
        }
    }
    return ret;
};

var jsonLightPayloadInfo = function (data, model) {
    /// <summary>Infers the information describing the JSON light payload from its metadata annotation, structure, and data model.</summary>
    /// <param name="data" type="Object">Json light response payload object.</param>
    /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
    /// <remarks>
    ///     If the arguments passed to the function don't convey enough information about the payload to determine without doubt that the payload is a feed then it
    ///     will try to use the payload object structure instead.  If the payload looks like a feed (has value property that is an array or non-primitive values) then
    ///     the function will report its kind as PAYLOADTYPE_FEED unless the inferFeedAsComplexType flag is set to true. This flag comes from the user request
    ///     and allows the user to control how the library behaves with an ambigous JSON light payload.
    /// </remarks>
    /// <returns type="Object">
    ///     Object with kind and type fields. Null if there is no metadata annotation or the payload info cannot be obtained..
    /// </returns>

    var metadataUri = data[contextUrlAnnotation];
    if (!metadataUri || typeof metadataUri !== "string") {
        return null;
    }

    var fragmentStart = metadataUri.lastIndexOf("#");
    if (fragmentStart === -1) {
        return jsonLightMakePayloadInfo(PAYLOADTYPE_SVCDOC);
    }

    var fragment = metadataUri.substring(fragmentStart + 1);
    return parseContextUriFragment(fragment,model);
};

var jsonLightReadPayload = function (data, model, demandedFormat,recognizeDates, inferFeedAsComplexType, contentTypeOdata) {
    /// <summary>Converts a JSON light response payload object into its library's internal representation.</summary>
    /// <param name="data" type="Object">Json light response payload object.</param>
    /// <param name="model" type="Object">Object describing an OData conceptual schema.</param>
    /// <param name="recognizeDates" type="Boolean" optional="true">Flag indicating whether datetime literal strings should be converted to JavaScript Date objects.</param>
    /// <param name="inferFeedAsComplexType" type="Boolean">True if a JSON light payload that looks like a feed should be reported as a complex type property instead.</param>
    /// <param name="contentTypeOdata" type="string">Includes the type of json ( minimalmetadata, fullmetadata .. etc )</param>
    /// <returns type="Object">Object in the library's representation.</returns>

    if (!isComplex(data)) {
        return data;
    }

    contentTypeOdata = contentTypeOdata || "minimal";
    var baseURI = data[contextUrlAnnotation];
    var payloadInfo = jsonLightPayloadInfo(data, model, inferFeedAsComplexType);
    if (assigned(payloadInfo)) {
        payloadInfo.contentTypeOdata = contentTypeOdata;
    }
    var typeName = null;
    if (payloadInfo) {
        delete data[contextUrlAnnotation];

        typeName = payloadInfo.type;
        switch (payloadInfo.detectedPayloadKind) {
            case PAYLOADTYPE_FEED:
                return jsonLightReadFeed(data, payloadInfo, baseURI, model, demandedFormat,recognizeDates);
            case PAYLOADTYPE_COLLECTION:
                return jsonLightReadTopCollectionProperty(data, typeName, baseURI, model, recognizeDates);
            case PAYLOADTYPE_PRIMITIVE:
                return jsonLightReadTopPrimitiveProperty(data, typeName, baseURI, recognizeDates);
            case PAYLOADTYPE_SVCDOC:
                return jsonLightReadSvcDocument(data, baseURI);
            case PAYLOADTYPE_LINKS:
                return jsonLightReadLinksDocument(data, baseURI);
        }
    }
    return jsonLightReadObject(data, payloadInfo, baseURI, model, recognizeDates);
};

var jsonLightGetEntryKey = function (data, entityModel) {
    /// <summary>Gets the key of an entry.</summary>
    /// <param name="data" type="Object">JSON light entry.</param>
    /// <param name="entityModel" type="String">Object describing the entry Model</param>
    /// <returns type="string">Entry instance key.</returns>

    var entityInstanceKey;
    var entityKeys = entityModel.key[0].propertyRef;
    var type;
    entityInstanceKey = "(";
    if (entityKeys.length == 1) {
        type = lookupProperty(entityModel.property, entityKeys[0].name).type;
        entityInstanceKey += formatLiteral(data[entityKeys[0].name], type);
    } else {
        var first = true;
        for (var i = 0; i < entityKeys.length; i++) {
            if (!first) {
                entityInstanceKey += ",";
            } else {
                first = false;
            }
            type = lookupProperty(entityModel.property, entityKeys[i].name).type;
            entityInstanceKey += entityKeys[i].name + "=" + formatLiteral(data[entityKeys[i].name], type);
        }
    }
    entityInstanceKey += ")";
    return entityInstanceKey;
};



var jsonLightReadFeed = function (data, feedInfo, baseURI, model, demandedFormat,recognizeDates) {
    var entries = [];
    var items = data.value;
    for (i = 0, len = items.length; i < len; i++) {
        //TODO SK check if items[i] has @odata.type and use this type instead of  feedinfo
        
        if ( items[i]['@odata.type'] !== undefined) {
            var typeName = items[i]['@odata.type'].substring(1);
            var type = lookupEntityType( typeName, model);
            var entryInfo = {
                contentTypeOdata : feedInfo.contentTypeOdata,
                detectedPayloadKind : feedInfo.detectedPayloadKind,
                name : feedInfo.name,
                type : type,
                typeName : typeName
            };

            entry = jsonLightReadObject(items[i], entryInfo, baseURI, model, demandedFormat,recognizeDates);
        } else {
            entry = jsonLightReadObject(items[i], feedInfo, baseURI, model, demandedFormat,recognizeDates);
        }
        
        entries.push(entry);
    }
    data.value = entries;
    return data;
};













/*
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 formatLiteral = function (value, type) {
    /// <summary>Formats a value according to Uri literal format</summary>
    /// <param name="value">Value to be formatted.</param>
    /// <param name="type">Edm type of the value</param>
    /// <returns type="string">Value after formatting</returns>

    value = "" + formatRowLiteral(value, type);
    value = encodeURIComponent(value.replace("'", "''"));
    switch ((type)) {
        case "Edm.Binary":
            return "X'" + value + "'";
        case "Edm.DateTime":
            return "datetime" + "'" + value + "'";
        case "Edm.DateTimeOffset":
            return "datetimeoffset" + "'" + value + "'";
        case "Edm.Decimal":
            return value + "M";
        case "Edm.Guid":
            return "guid" + "'" + value + "'";
        case "Edm.Int64":
            return value + "L";
        case "Edm.Float":
            return value + "f";
        case "Edm.Double":
            return value + "D";
        case "Edm.Geography":
            return "geography" + "'" + value + "'";
        case "Edm.Geometry":
            return "geometry" + "'" + value + "'";
        case "Edm.Time":
            return "time" + "'" + value + "'";
        case "Edm.String":
            return "'" + value + "'";
        default:
            return value;
    }
};

var formatRowLiteral = function (value, type) {
    switch (type) {
        case "Edm.Binary":
            return convertByteArrayToHexString(value);
        default:
            return value;
    }
};





var checkProperties = function(data,objectInfoType,baseURI,model, demandedFormat, recognizeDates) {
    for (var name in data) {
        if (name.indexOf("@") === -1) {
            var curType = objectInfoType;
            var propertyValue = data[name];
            var property = lookupProperty(curType.property,name); //TODO SK add check for parent type

            while (( property === null) && (curType.baseType !== undefined)) {
                curType = lookupEntityType(curType.baseType, model);
                property = lookupProperty(curType.property,name);
            }
            
            if ( isArray(propertyValue)) {
                data[name+'@odata.type'] = '#' + property.type;
                for ( var i = 0; i < propertyValue.length; i++) {
                    jsonLightReadComplexObject(propertyValue[0], property,baseURI,model,demandedFormat, recognizeDates);
                }
            } else if (isObject(propertyValue) && (propertyValue !== null)) {
                jsonLightReadComplexObject(propertyValue, property,baseURI,model,demandedFormat, recognizeDates);
            } else {
                if (demandedFormat === 3)  {
                    data[name+'@odata.type'] = '#' + property.type;
                } else {
                    if ( property.type != "Edm.String" &&
                         property.type != "Edm.Boolean" &&
                         property.type != "Edm.Int32" &&
                         property.type != "Edm.Single" &&
                         property.type != "Edm.Double" ) {
                         data[name+'@odata.type'] = '#' + property.type;
                    }
                }
            }
        }
    }
};

var jsonLightReadComplexObject = function (data, property, baseURI, model, demandedFormat, recognizeDates) {
    var type = property.type;
    if (isCollectionType(property.type)) {
        type =property.type.substring(11,property.type.length-1);
    }

    data['@odata.type'] = '#'+type;



    var propertyType = lookupComplexType(type, model);
    if (propertyType === null)  {
        return; //TODO check what to do if the type is not known e.g. type #GeometryCollection
    }
  

    checkProperties(data,propertyType ,baseURI,model, demandedFormat, recognizeDates);
};

var jsonLightReadObject = function (data, objectInfo, baseURI, model, demandedFormat, recognizeDates) {
    //var obj = {};

    data['@odata.type'] = '#'+objectInfo.typeName;

    var keyType = objectInfo.type;
    while (( keyType.key === undefined) && (keyType.baseType !== undefined)) {
        keyType = lookupEntityType(keyType.baseType, model);
    }

    var lastIdSegment = objectInfo.name + jsonLightGetEntryKey(data, keyType);
    data['@odata.id'] = baseURI.substring(0, baseURI.lastIndexOf("$metadata")) + lastIdSegment;
    data['@odata.editLink'] = lastIdSegment;

    var serviceURI = baseURI.substring(0, baseURI.lastIndexOf("$metadata"));
    //jsonLightComputeUrisIfMissing(data, entryInfo, actualType, serviceURI, dataModel, baseTypeModel);

    checkProperties(data,objectInfo.type,baseURI,model, demandedFormat, recognizeDates);
    
    return data;
};


var jsonHandler = oDataHandler.handler(jsonParser, jsonSerializer, jsonMediaType, MAX_DATA_SERVICE_VERSION);
jsonHandler.recognizeDates = false;
jsonHandler.useJsonLight = true;
jsonHandler.inferJsonLightFeedAsObject = false;

exports.jsonHandler = jsonHandler;

// DATAJS INTERNAL START
exports.jsonParser = jsonParser;
exports.jsonSerializer = jsonSerializer;

exports.parseJsonDateString = parseJsonDateString;
exports.jsonLightPayloadInfo = jsonLightPayloadInfo;
// DATAJS INTERNAL END

//exports.jsonNormalizeData = jsonNormalizeData;
//exports.normalizeServiceDocument = normalizeServiceDocument;

/*
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") {
                        if (propertyValue) {
                            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] };
};*/