﻿/// <summary>
/// Class used to parse the Content section of the feed to return the properties data and metadata
/// </summary>

namespace DataJS.Tests
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Web.Script.Serialization;
    using System.Xml;
    using Microsoft.Data.Edm;
    using Microsoft.Data.Edm.Csdl;

    public static class JsonLightReader
    {
        private static Dictionary<string, string> nameMap = new Dictionary<string, string>() {
            {"readLink", "self"},
            {"editLink", "edit"},
            {"nextLink", "__next"},
            {"mediaReadLink", "media_src"},
            {"mediaEditLink", "edit_media"},
            {"mediaContentType", "content_type"},
            {"mediaETag", "media_etag"},
            {"count", "__count"},
            {"media_src", "mediaReadLink"},
            {"edit_media", "mediaEditLink"},
            {"content_type", "mediaContentType"},
            {"media_etag", "mediaETag"},
            {"url", "uri"}
        };

        public static JsonObject ReadJsonLight(TextReader payload)
        {
            var serializer = new JavaScriptSerializer();
            serializer.RegisterConverters(new JavaScriptConverter[] { new JsonObjectConverter() });

            var json = serializer.Deserialize<JsonObject>(payload.ReadToEnd());

            IEdmModel model = null;
            string metadataFragment = null;
            string metadataURI = json["odata.metadata"] as string;

            if (metadataURI != null)
            {
                int fragmentStart = metadataURI.IndexOf("#");
                string metadataUrl = metadataURI;

                if (fragmentStart > 0)
                {
                    metadataUrl = metadataURI.Substring(0, fragmentStart);
                    metadataFragment = metadataURI.Substring(fragmentStart + 1);
                }
                model = GetEndpointModel(metadataUrl);
            }
        }

        private static IEdmModel GetEndpointModel(string modelUrl)
        {
            using (WebResponse response = ReaderUtils.CreateRequest(modelUrl).GetResponse())
            {
                return EdmxReader.Parse(XmlReader.Create(response.GetResponseStream()));
            }
        }

        private static JsonObject ReadObject(JsonObject jsonLight, IEdmModel model)
        {
            var json = new JsonObject();
            var metadata = json["__metadata"] = new JsonObject();

            foreach (var item in jsonLight)
            {
                string name = item.Key;
                if (name.IndexOf(".", StringComparison.OrdinalIgnoreCase) == -1)
                {
                    if (item.Value is JsonObject)
                    {
                        json[item.Key] = ReadObject((JsonObject)item.Value, model);
                    }
                }
            }

            return json;
        }

        private static JsonObject ReadObjectProperties(IEnumerable<KeyValuePair<string, object>> properties, JsonObject json)
        {
            return json;
        }

        private static JsonObject ApplyPayloadAnnotationsToObject(IEnumerable<KeyValuePair<string, object>> annotations, JsonObject json)
        {
            foreach (var item in annotations)
            {
                ApplyPayloadAnnotationToObject(item.Key, item.Value, json);
            }
            return json;
        }

        private static JsonObject ApplyPayloadAnnotationToObject(string annotation, object value, JsonObject json)
        {
            int index = annotation.IndexOf("@", StringComparison.OrdinalIgnoreCase);
            string target = null;
            string name = annotation;

            if (index > 0)
            {
                target = annotation.Substring(0, index);
                name = annotation.Substring(index + 1);
            }

            if (name.StartsWith("odata.", StringComparison.Ordinal))
            {
                return ApplyODataPayloadAnnotation(name, target, value, json);
            }

            json["annotation"] = value;
            return json;
        }

        private static JsonObject ApplyODataPayloadAnnotation(string annotation, string target, string targetType, object value, Uri baseUri, JsonObject json)
        {
            string name = annotation.Substring("odata.".Length);
            switch (name)
            {
                case "navigationLinkUrl":
                    return ApplyNavigationUrlAnnotation(name, target, targetType, value, baseUri, json);
                case "nextLink":
                case "count":
                    return ApplyFeedAnnotation(name, target, value, baseUri, json);
                case "mediaReadLink":
                case "mediaEditLink":
                case "mediaContentType":
                case "mediaETag":
                    return ApplyMediaAnnotation(name, target, targetType, value, baseUri, json);
                default:
                    return ApplyMetadataAnnotation(name, target, targetType, value, baseUri, json);
            }
        }

        private static JsonObject ApplyNavigationUrlAnnotation(string name, string target, string targetType, object value, Uri baseUri, JsonObject json)
        {
            JsonObject propertiesMetadata = GetOrCreatePropertiesMetadata(json);
            JsonObject propertyMetadata = GetOrCreateObjectProperty(propertiesMetadata, target);

            string uri = NormalizeUri((string)value, baseUri);

            if (json.ContainsKey(target))
            {
                propertyMetadata["navigationLinkUrl"] = uri;
            }
            else
            {
                JsonObject navProp = new JsonObject();
                JsonObject deferred = new JsonObject();

                deferred["uri"] = uri;
                navProp["__deferred"] = deferred;
                json[target] = navProp;

                if (!propertyMetadata.ContainsKey("type"))
                {
                    propertyMetadata["type"] = targetType;
                }
            }
            return json;
        }

        private static JsonObject ApplyFeedAnnotation(string name, string target, object value, Uri baseUri, JsonObject json)
        {
            string mappedName = MapODataName(name);
            JsonObject feed = (target == null) ? json : (JsonObject)json[target];
            feed[mappedName] = (name == "nextLink") ? NormalizeUri((string)value, baseUri) : value;
            return json;
        }

        private static JsonObject ApplyMediaAnnotation(string name, string target, string targetType, object value, Uri baseUri, JsonObject json)
        {
            string mappedName = MapODataName(name);
            object theValue = value;

            if (name == "mediaReadLink" || name == "mediaEditLink")
            {
                theValue = NormalizeUri((string)value, baseUri);
            }

            if (target != null)
            {
                JsonObject propertiesMetadata = GetOrCreatePropertiesMetadata(json);
                JsonObject propertyMetadata = GetOrCreateObjectProperty(propertiesMetadata, target);
                JsonObject namedStream = GetOrCreateObjectProperty(json, target);
                JsonObject mediaResource = GetOrCreateObjectProperty(namedStream, "__mediaresource");

                if (!propertyMetadata.ContainsKey("type") || propertyMetadata["type"] == null)
                {
                    propertyMetadata["type"] = targetType;
                }
                mediaResource[mappedName] = theValue;
            }
            else
            {
                JsonObject metadata = GetOrCreateObjectMetadata(json);
                metadata[mappedName] = value;
            }
            return json;
        }

        private static JsonObject ApplyMetadataAnnotation(string name, string target, string targetType, object value, Uri baseUri, JsonObject json)
        {
            string mappedName = MapODataName(name);
            JsonObject metadata = GetOrCreateObjectMetadata(json);

            if (name == "editLink")
            {
                metadata["uri"] = NormalizeUri((string)value, baseUri);
                metadata[mappedName] = metadata["uri"];
                return json;
            }

            if (name == "readLink" || name == "associationLinkUrl")
            {
                metadata[mappedName] = NormalizeUri((string)value, baseUri);
                return json;
            }

            if (target != null)
            {
                JsonObject propertiesMetadata = GetOrCreatePropertiesMetadata(json);
                JsonObject propertyMetadata = GetOrCreateObjectProperty(propertiesMetadata, target);

                if (name == "type")
                {
                    if (!propertyMetadata.ContainsKey("type") || propertyMetadata["type"] == null)
                    {
                        propertyMetadata["type"] = targetType;
                        return json;
                    }
                }
                propertyMetadata[mappedName] = value;
                return json;
            }
            metadata[mappedName] = value;
            return json;
        }

        private static string MapODataName(string name)
        {
            return nameMap.ContainsKey(name) ? nameMap[name] : name;
        }

        private static JsonObject GetOrCreateObjectProperty(JsonObject json, string name)
        {
            if (!json.ContainsKey(name))
            {
                json[name] = new JsonObject();
            }
            return (JsonObject)json[name];
        }

        private static JsonObject GetOrCreateObjectMetadata(JsonObject json)
        {
            return GetOrCreateObjectProperty(json, "__metadata");
        }

        private static JsonObject GetOrCreatePropertiesMetadata(JsonObject json)
        {
            JsonObject metadata = GetOrCreateObjectMetadata(json);
            return GetOrCreateObjectProperty(metadata, "properties");
        }

        private static string NormalizeUri(string uri, Uri baseUri)
        {
            Uri tmpUri = new Uri(uri, UriKind.RelativeOrAbsolute);

            if (!tmpUri.IsAbsoluteUri && baseUri != null)
            {
                tmpUri = new Uri(baseUri, tmpUri);
                return tmpUri.AbsoluteUri;
            }
            return tmpUri.OriginalString;
        }

        private class JsonObjectConverter : JavaScriptConverter
        {
            public override object Deserialize(IDictionary<string, object> dictionary, System.Type type, JavaScriptSerializer serializer)
            {
                var json = new JsonObject();
                foreach (var item in dictionary)
                {
                    object value = item.Value;
                    if (value is IDictionary<string, object>)
                    {
                        value = serializer.ConvertToType<JsonObject>(value);
                    }
                    json[item.Key] = value;
                }
                return json;
            }

            public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
            {
                throw new System.NotImplementedException();
            }

            public override IEnumerable<Type> SupportedTypes
            {
                get { return new Type[] { typeof(JsonObject) }; }
            }
        }

    }
}