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

using System;
using System.Collections;
using System.IO;

namespace Apache.NMS.Util
{
    /// <summary>
    /// A default implementation of IPrimitiveMap
    /// </summary>
    public class PrimitiveMap : IPrimitiveMap
    {
        public const byte NULL = 0;
        public const byte BOOLEAN_TYPE = 1;
        public const byte BYTE_TYPE = 2;
        public const byte CHAR_TYPE = 3;
        public const byte SHORT_TYPE = 4;
        public const byte INTEGER_TYPE = 5;
        public const byte LONG_TYPE = 6;
        public const byte DOUBLE_TYPE = 7;
        public const byte FLOAT_TYPE = 8;
        public const byte STRING_TYPE = 9;
        public const byte BYTE_ARRAY_TYPE = 10;
        public const byte MAP_TYPE = 11;
        public const byte LIST_TYPE = 12;
        public const byte BIG_STRING_TYPE = 13;

        private IDictionary dictionary = Hashtable.Synchronized(new Hashtable());

        public void Clear()
        {
            dictionary.Clear();
        }

        public bool Contains(Object key)
        {
            return dictionary.Contains(key);
        }

        public void Remove(Object key)
        {
            dictionary.Remove(key);
        }

        public int Count
        {
            get { return dictionary.Count; }
        }

        public ICollection Keys
        {
            get
            {
                lock (dictionary.SyncRoot) return new ArrayList(dictionary.Keys);
            }
        }

        public ICollection Values
        {
            get
            {
                lock (dictionary.SyncRoot) return new ArrayList(dictionary.Values);
            }
        }

        public object this[string key]
        {
            get { return GetValue(key); }
            set
            {
                CheckValidType(value);
                SetValue(key, value);
            }
        }

        public string GetString(string key)
        {
            Object value = GetValue(key);
            if (value == null)
            {
                return null;
            }

            CheckValueType(value, typeof(string));
            return (string) value;
        }

        public void SetString(string key, string value)
        {
            SetValue(key, value);
        }

        public bool GetBool(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(bool));
            return (bool) value;
        }

        public void SetBool(String key, bool value)
        {
            SetValue(key, value);
        }

        public byte GetByte(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(byte));
            return (byte) value;
        }

        public void SetByte(String key, byte value)
        {
            SetValue(key, value);
        }

        public char GetChar(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(char));
            return (char) value;
        }

        public void SetChar(String key, char value)
        {
            SetValue(key, value);
        }

        public short GetShort(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(short));
            return (short) value;
        }

        public void SetShort(String key, short value)
        {
            SetValue(key, value);
        }

        public int GetInt(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(int));
            return (int) value;
        }

        public void SetInt(String key, int value)
        {
            SetValue(key, value);
        }

        public long GetLong(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(long));
            return (long) value;
        }

        public void SetLong(String key, long value)
        {
            SetValue(key, value);
        }

        public float GetFloat(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(float));
            return (float) value;
        }

        public void SetFloat(String key, float value)
        {
            SetValue(key, value);
        }

        public double GetDouble(String key)
        {
            Object value = GetValue(key);
            CheckValueType(value, typeof(double));
            return (double) value;
        }

        public void SetDouble(String key, double value)
        {
            SetValue(key, value);
        }

        public IList GetList(String key)
        {
            Object value = GetValue(key);
            if (value != null && !(value is IList))
            {
                throw new NMSException("Property: " + key + " is not an IList but is: " + value);
            }

            return (IList) value;
        }

        public void SetList(String key, IList value)
        {
            SetValue(key, value);
        }

        public void SetBytes(String key, byte[] value)
        {
            this.SetBytes(key, value, 0, value.Length);
        }

        public void SetBytes(String key, byte[] value, int offset, int length)
        {
            byte[] copy = new byte[length];
            Array.Copy(value, offset, copy, 0, length);
            SetValue(key, copy);
        }

        public byte[] GetBytes(string key)
        {
            Object value = GetValue(key);
            if (value != null && !(value is Byte[]))
            {
                throw new NMSException("Property: " + key + " is not an byte[] but is: " + value);
            }

            return (byte[]) value;
        }

        public IDictionary GetDictionary(String key)
        {
            Object value = GetValue(key);
            if (value != null && !(value is IDictionary))
            {
                throw new NMSException("Property: " + key + " is not an IDictionary but is: " + value);
            }

            return (IDictionary) value;
        }

        public void SetDictionary(String key, IDictionary value)
        {
            SetValue(key, value);
        }

        protected virtual void SetValue(String key, Object value)
        {
            dictionary[key] = value;
        }

        protected virtual Object GetValue(String key)
        {
            return dictionary[key];
        }

        protected virtual void CheckValueType(Object value, Type type)
        {
            if (!type.IsInstanceOfType(value))
            {
                throw new NMSException("Expected type: " + type.Name + " but was: " + value);
            }
        }

        protected virtual void CheckValidType(Object value)
        {
            if (value != null && !(value is IList) && !(value is IDictionary))
            {
                Type type = value.GetType();

                if (type.IsInstanceOfType(typeof(Object)) ||
                    (!type.IsPrimitive && !type.IsValueType && !type.IsAssignableFrom(typeof(string))))
                {
                    throw new NMSException("Invalid type: " + type.Name + " for value: " + value);
                }
            }
        }

        /// <summary>
        /// Method ToString
        /// </summary>
        /// <returns>A string</returns>
        public override String ToString()
        {
            String s = "{";
            bool first = true;
            lock (dictionary.SyncRoot)
            {
                foreach (DictionaryEntry entry in dictionary)
                {
                    if (!first)
                    {
                        s += ", ";
                    }

                    first = false;
                    String name = (String) entry.Key;
                    Object value = entry.Value;
                    s += name + "=" + value;
                }
            }

            s += "}";
            return s;
        }

        /// <summary>
        /// Unmarshalls the map from the given data or if the data is null just
        /// return an empty map
        /// </summary>
        public static PrimitiveMap Unmarshal(byte[] data)
        {
            PrimitiveMap answer = new PrimitiveMap();
            answer.dictionary = UnmarshalPrimitiveMap(data);
            return answer;
        }

        /// <summary>
        /// Unmarshals a PrimitiveMap directly from a Stream object.  This 
        /// allows for clients to read PrimitiveMaps from Compressed or other
        /// wise encoded streams without this class needing to know about it.
        /// </summary>
        /// <param name="source">
        /// A <see cref="Stream"/>
        /// </param>
        /// <returns>
        /// A <see cref="PrimitiveMap"/>
        /// </returns>
        public static PrimitiveMap Unmarshal(Stream source)
        {
            PrimitiveMap answer = new PrimitiveMap();
            answer.dictionary = UnmarshalPrimitiveMap(source);
            return answer;
        }

        public byte[] Marshal()
        {
            lock (dictionary.SyncRoot)
            {
                return MarshalPrimitiveMap(dictionary);
            }
        }

        /// <summary>
        /// Marshals a PrimitiveMap directly to a Stream object.  This
        /// allows a client to write a PrimitiveMap in a compressed or 
        /// otherwise encoded form without this class needing to know 
        /// about it.
        /// </summary>
        /// <param name="destination">
        /// A <see cref="Stream"/>
        /// </param>
        public void Marshal(Stream destination)
        {
            lock (dictionary.SyncRoot)
            {
                MarshalPrimitiveMap(dictionary, destination);
            }
        }

        /// <summary>
        /// Marshals the primitive type map to a byte array
        /// </summary>
        public static byte[] MarshalPrimitiveMap(IDictionary map)
        {
            if (map == null)
            {
                return null;
            }

            MemoryStream memoryStream = new MemoryStream();
            lock (map.SyncRoot)
            {
                MarshalPrimitiveMap(map, new EndianBinaryWriter(memoryStream));
            }

            return memoryStream.ToArray();
        }

        public static void MarshalPrimitiveMap(IDictionary map, Stream stream)
        {
            if (map != null)
            {
                lock (map.SyncRoot)
                {
                    MarshalPrimitiveMap(map, new EndianBinaryWriter(stream));
                }
            }
        }

        public static void MarshalPrimitiveMap(IDictionary map, BinaryWriter dataOut)
        {
            if (map == null)
            {
                dataOut.Write((int) -1);
            }
            else
            {
                lock (map.SyncRoot)
                {
                    dataOut.Write(map.Count);
                    foreach (DictionaryEntry entry in map)
                    {
                        String name = (String) entry.Key;
                        dataOut.Write(name);
                        Object value = entry.Value;
                        MarshalPrimitive(dataOut, value);
                    }
                }
            }
        }

        /// <summary>
        /// Unmarshals the primitive type map from the given byte array
        /// </summary>
        public static IDictionary UnmarshalPrimitiveMap(byte[] data)
        {
            if (data == null)
            {
                return new Hashtable();
            }
            else
            {
                return UnmarshalPrimitiveMap(new EndianBinaryReader(new MemoryStream(data)));
            }
        }

        public static IDictionary UnmarshalPrimitiveMap(Stream source)
        {
            return UnmarshalPrimitiveMap(new EndianBinaryReader(source));
        }

        public static IDictionary UnmarshalPrimitiveMap(BinaryReader dataIn)
        {
            int size = dataIn.ReadInt32();
            if (size < 0)
            {
                return null;
            }

            IDictionary answer = new Hashtable(size);
            for (int i = 0; i < size; i++)
            {
                String name = dataIn.ReadString();
                answer[name] = UnmarshalPrimitive(dataIn);
            }

            return answer;
        }

        public static void MarshalPrimitiveList(IList list, BinaryWriter dataOut)
        {
            dataOut.Write((int) list.Count);
            foreach (Object element in list)
            {
                MarshalPrimitive(dataOut, element);
            }
        }

        public static IList UnmarshalPrimitiveList(BinaryReader dataIn)
        {
            int size = dataIn.ReadInt32();
            IList answer = new ArrayList(size);
            while (size-- > 0)
            {
                answer.Add(UnmarshalPrimitive(dataIn));
            }

            return answer;
        }

        public static void MarshalPrimitive(BinaryWriter dataOut, Object value)
        {
            if (value == null)
            {
                dataOut.Write(NULL);
            }
            else if (value is bool)
            {
                dataOut.Write(BOOLEAN_TYPE);
                dataOut.Write((bool) value);
            }
            else if (value is byte)
            {
                dataOut.Write(BYTE_TYPE);
                dataOut.Write(((byte) value));
            }
            else if (value is char)
            {
                dataOut.Write(CHAR_TYPE);
                dataOut.Write((char) value);
            }
            else if (value is short)
            {
                dataOut.Write(SHORT_TYPE);
                dataOut.Write((short) value);
            }
            else if (value is int)
            {
                dataOut.Write(INTEGER_TYPE);
                dataOut.Write((int) value);
            }
            else if (value is long)
            {
                dataOut.Write(LONG_TYPE);
                dataOut.Write((long) value);
            }
            else if (value is float)
            {
                dataOut.Write(FLOAT_TYPE);
                dataOut.Write((float) value);
            }
            else if (value is double)
            {
                dataOut.Write(DOUBLE_TYPE);
                dataOut.Write((double) value);
            }
            else if (value is byte[])
            {
                byte[] data = (byte[]) value;
                dataOut.Write(BYTE_ARRAY_TYPE);
                dataOut.Write(data.Length);
                dataOut.Write(data);
            }
            else if (value is string)
            {
                string s = (string) value;
                // is the string big??
                if (s.Length > 8191)
                {
                    dataOut.Write(BIG_STRING_TYPE);
                    ((EndianBinaryWriter) dataOut).WriteString32(s);
                }
                else
                {
                    dataOut.Write(STRING_TYPE);
                    ((EndianBinaryWriter) dataOut).WriteString16(s);
                }
            }
            else if (value is IDictionary)
            {
                dataOut.Write(MAP_TYPE);
                MarshalPrimitiveMap((IDictionary) value, dataOut);
            }
            else if (value is IList)
            {
                dataOut.Write(LIST_TYPE);
                MarshalPrimitiveList((IList) value, dataOut);
            }
            else
            {
                throw new IOException("Object is not a primitive: " + value);
            }
        }

        public static Object UnmarshalPrimitive(BinaryReader dataIn)
        {
            Object value = null;
            byte type = dataIn.ReadByte();
            switch (type)
            {
                case NULL:
                    value = null;
                    break;
                case BYTE_TYPE:
                    value = dataIn.ReadByte();
                    break;
                case BOOLEAN_TYPE:
                    value = dataIn.ReadBoolean();
                    break;
                case CHAR_TYPE:
                    value = dataIn.ReadChar();
                    break;
                case SHORT_TYPE:
                    value = dataIn.ReadInt16();
                    break;
                case INTEGER_TYPE:
                    value = dataIn.ReadInt32();
                    break;
                case LONG_TYPE:
                    value = dataIn.ReadInt64();
                    break;
                case FLOAT_TYPE:
                    value = dataIn.ReadSingle();
                    break;
                case DOUBLE_TYPE:
                    value = dataIn.ReadDouble();
                    break;
                case BYTE_ARRAY_TYPE:
                    int size = dataIn.ReadInt32();
                    byte[] data = new byte[size];
                    dataIn.Read(data, 0, size);
                    value = data;
                    break;
                case STRING_TYPE:
                    value = ((EndianBinaryReader) dataIn).ReadString16();
                    break;
                case BIG_STRING_TYPE:
                    value = ((EndianBinaryReader) dataIn).ReadString32();
                    break;
                case MAP_TYPE:
                    value = UnmarshalPrimitiveMap(dataIn);
                    break;
                case LIST_TYPE:
                    value = UnmarshalPrimitiveList(dataIn);
                    break;

                default:
                    throw new Exception("Unsupported data type: " + type);
            }

            return value;
        }
    }
}