using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace AyaNova.Util
{


    internal static class JsonUtil
    {

        /// <summary>
        /// Clean JSON string fragment, remove unnecessary characters
        /// can be called with anything and should handle it properly even empty values etc
        /// </summary>
        /// <param name="jsonIn"></param>
        /// <returns></returns>
        public static string CompactJson(string jsonIn)
        {
            if (string.IsNullOrWhiteSpace(jsonIn))
            {
                return jsonIn;
            }
            if (jsonIn.StartsWith("["))
            {
                JArray j = JArray.Parse(jsonIn);
                return JsonConvert.SerializeObject(j, Formatting.None);
            }
            if (jsonIn.StartsWith("{"))
            {
                JObject j = JObject.Parse(jsonIn);
                return JsonConvert.SerializeObject(j, Formatting.None);
            }
            //Not an object or an array so just return it
            return jsonIn;
        }


        /// <summary>
        /// Utility used by biz classes to extract all the custom field data as text strings suitable for search indexing
        /// Does not take into account type of field only what is in it and weeds out bools and any other non suitable for search text
        /// </summary>
        /// <param name="jsonIn"></param>
        /// <returns></returns>
        public static List<string> GetCustomFieldsAsStringArrayForSearchIndexing(string jsonIn)
        {
            var ret = new List<string>();

            if (!string.IsNullOrWhiteSpace(jsonIn))
            {
                var j = JObject.Parse(jsonIn);

                //iterate the values in the custom fields
                foreach (KeyValuePair<string, JToken> kv in j)
                {
                    //Add as string any value that isn't a bool since bools are useless for searching
                    //and don't add dates as it gets hellish to factor in time zone conversions and local server vs user date format and all that shit
                    //and at the end of the day it won't really be useful for searching as people will probably ask for a filter or sort instead which we may have to 
                    //look at in future, for search though just the numbers and text that are plausibly search-worthy
                    if (kv.Value.Type != JTokenType.Boolean && kv.Value.Type != JTokenType.Date)
                    {
                        ret.Add(kv.Value.Value<string>());
                    }
                }
            }
            return ret;
        }

        //Contract resolver used for exporting to file translations and report templates
        //and ignoring specified propertes
        public class ShouldSerializeContractResolver : DefaultContractResolver
        {
            private readonly IEnumerable<string> _excludePropertyNames;
            public ShouldSerializeContractResolver(IEnumerable<string> excludePropertyNames)
            {
                _excludePropertyNames = excludePropertyNames;
            }
            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
                properties = properties.Where(p => !_excludePropertyNames.Any(p2 => p2 == p.PropertyName)).ToList();
                return properties;
            }
        }



    }//eoc

}//eons