/*
 *
 * 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.Text;
using log4net;
using Qpid.Buffer;
using Qpid.Collections;
using Qpid.Messaging;

namespace Qpid.Framing
{
    public class FieldTable : IFieldTable, IEnumerable
    {
        private static readonly ILog _log = LogManager.GetLogger(typeof(FieldTable));

        IDictionary _properties;
        private ByteBuffer _encodedForm;
        private object _syncLock;
        private uint _encodedSize;

        public FieldTable()
        {
           _syncLock = new object();
        }
        
        /// <summary>
        /// Construct a new field table.
        /// </summary>
        /// <param name="buffer">the buffer from which to read data. The length byte must be read already</param>
        /// <param name="length">the length of the field table. Must be > 0.</param>
        /// <exception cref="AMQFrameDecodingException">if there is an error decoding the table</exception>
        public FieldTable(ByteBuffer buffer, uint length) : this()
        {
           _encodedForm = buffer.slice();
           _encodedForm.limit((int)length);
           _encodedSize = length;
           buffer.skip((int)length);
        }

        /// <summary>
        /// The set of all property names
        /// </summary>
        public ICollection Keys
        {
           get 
           { 
              InitMapIfNecessary();
              return _properties.Keys;  
           }
        }

        /// <summary>
        /// Calculated size of this field table once encoded
        /// </summary>
        public uint EncodedSize
        {
           get { return _encodedSize; }
        }

        /// <summary>
        /// Number of properties in the field table
        /// </summary>
        public int Count
        {
           get
           {
              InitMapIfNecessary();
              return _properties.Count;
           }
        }

        /// <summary>
        /// Gets or sets the specified property.
        /// </summary>
        /// <param name="key">Property name</param>
        /// <returns>The specified property value</returns>
        public object this[string key]
        { 
           get { return GetObject(key); }
           set { SetObject(key, value); }
        }

        #region Typed Setters and Getters
        //
        // Typed Setters and Getters
        //
        public bool GetBoolean(string key)
        {
           return (bool)this[key];
        }
        public void SetBoolean(string key, bool value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.BOOLEAN.AsTypedValue(value));
        }
        public byte GetByte(string key)
        {
           return (byte)this[key];
        }
        public void SetByte(string key, byte value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.BYTE.AsTypedValue(value));
        }
        public sbyte GetSByte(string key)
        {
           return (sbyte)this[key];
        }
        public void SetSByte(string key, sbyte value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.SBYTE.AsTypedValue(value));
        }
        public short GetInt16(string key)
        {
           return (short)this[key];
        }
        public void SetInt16(string key, short value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.INT16.AsTypedValue(value));
        }
        public int GetInt32(string key)
        {
           return (int)this[key];
        }
        public void SetInt32(string key, int value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.INT32.AsTypedValue(value));
        }
        public long GetInt64(string key)
        {
           return (long)this[key];
        }
        public void SetInt64(string key, long value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.INT64.AsTypedValue(value));
        }
        public char GetChar(string key)
        {
           return (char)this[key];
        }
        public void SetChar(string key, char value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.ASCII_CHARACTER.AsTypedValue(value));
        }
        public float GetFloat(string key)
        {
           return (float)this[key];
        }
        public void SetFloat(string key, float value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.FLOAT.AsTypedValue(value));
        }
        public double GetDouble(string key)
        {
           return (double)this[key];
        }
        public void SetDouble(string key, double value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.DOUBLE.AsTypedValue(value));
        }
        public decimal GetDecimal(string key)
        {
           return (decimal)this[key];
        }
        public void SetDecimal(string key, decimal value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.DECIMAL.AsTypedValue(value));
        }
        public string GetString(string key)
        {
           return (string)this[key];
        }
        public void SetString(string key, string value)
        {
           CheckPropertyName(key);
           if ( value == null )
              SetProperty(key, AMQType.VOID.AsTypedValue(null));
           else
              SetProperty(key, AMQType.LONG_STRING.AsTypedValue(value));
        }
        public byte[] GetBytes(string key)
        {
           return (byte[])this[key];
        }
        public void SetBytes(string key, byte[] value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.BINARY.AsTypedValue(value));
        }
        public ushort GetUInt16(string key)
        {
           return (ushort)this[key];
        }
        public void SetUInt16(string key, ushort value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.UINT16.AsTypedValue(value));
        }
        public uint GetUInt32(string key)
        {
           return (uint)this[key];
        }
        public void SetUInt32(string key, uint value)
        { 
           CheckPropertyName(key);
           SetProperty(key, AMQType.UINT32.AsTypedValue(value));
        }
        public ulong GetUInt64(string key)
        {
           return (ulong)this[key];
        }
        public void SetUInt64(string key, ulong value)
        {
           CheckPropertyName(key);
           SetProperty(key, AMQType.UINT64.AsTypedValue(value));
        } 

        #endregion // Typed Setters and Getters

        #region Public Methods
        //
        // Public Methods
        //

        /// <summary>
        /// Removes the property with the specified name
        /// </summary>
        /// <param name="key">The name of the property to remove</param>
        /// <returns>The previous value of the property or null</returns>
        public AMQTypedValue RemoveKey(string key)
        {
           InitMapIfNecessary();
           _encodedForm = null;
           AMQTypedValue value = (AMQTypedValue)_properties[key];
           if ( value != null )
           {
              _properties.Remove(key);
              _encodedSize -= EncodingUtils.EncodedShortStringLength(key);
              _encodedSize--;
              _encodedSize -= value.EncodingLength;

           }
           return value;
        }
        

        /// <summary>
        /// Remove the property with the specified name
        /// </summary>
        /// <param name="key">The name of the property to remove</param>
        public void Remove(string key)
        {
           RemoveKey(key);
        }

        /// <summary>
        /// Remove all properties from the table
        /// </summary>
        public void Clear()
        {
           InitMapIfNecessary();
           _encodedForm = null;
           _properties.Clear();
           _encodedSize = 0;
        }

        /// <summary>
        /// Adds all the items from one field table in this one. Will overwrite any items in the current table
        /// with the same key.
        /// </summary>
        /// <param name="ft">the source field table</param>
        public void AddAll(IFieldTable ft)
        {
           foreach ( DictionaryEntry dictionaryEntry in ft )
           {
              this[(string)dictionaryEntry.Key] = dictionaryEntry.Value;
           }
        }

        /// <summary>
        /// Get a enumerator over the internal property set.
        /// Notice the enumerator will DictionaryEntry objects with 
        /// a string as the Key and an <see cref="AMQTypedValue"/> instance as the value
        /// </summary>
        /// <returns>The enumerator object</returns>
        public IEnumerator GetEnumerator()
        {
           return _properties.GetEnumerator();
        }

        /// <summary>
        /// Indicates if a property with the given name exists
        /// </summary>
        /// <param name="s">Property name to check</param>
        /// <returns>True if the property exists</returns>
        public bool Contains(string s)
        {
           return _properties.Contains(s);
        }
        
        /// <summary>
        /// Returns a dictionary mapping Property Names to the corresponding
        /// <see cref="AMQTypedValue"/> value
        /// </summary>
        /// <returns>The internal dictionary</returns>
        public IDictionary AsDictionary()
        {
           return _properties;
        }

        /// <summary>
        /// Returns a string representation of this field table
        /// </summary>
        /// <returns>A string</returns>
        public override string ToString()
        {
           StringBuilder sb = new StringBuilder("FieldTable {");

           bool first = true;
           InitMapIfNecessary();
           foreach ( DictionaryEntry entry in _properties )
           {
              if ( !first )
              {
                 sb.Append(", ");
              }
              first = false;
              sb.Append(entry.Key).Append(" => ").Append(entry.Value);
           }

           sb.Append("}");
           return sb.ToString();
        }
        
        /// <summary>
        /// Serializes this instance to the specified <see cref="ByteBuffer"/>.
        /// </summary>
        /// <param name="buffer">The buffer to write to</param>
        public void WriteToBuffer(ByteBuffer buffer)
        {
            if ( _log.IsDebugEnabled )
            {
               _log.Debug("FieldTable::writeToBuffer: Writing encoded length of " + EncodedSize + "...");
            }

           EncodingUtils.WriteUnsignedInteger(buffer, EncodedSize);
           WritePayload(buffer);
        }

        /// <summary>
        /// Returns a byte array with the serialized representation
        /// of this field table
        /// </summary>
        /// <returns>An array of bytes</returns>
        public byte[] GetDataAsBytes()
        {
           ByteBuffer buffer = ByteBuffer.allocate((int)_encodedSize);
           WritePayload(buffer);
           byte[] result = new byte[_encodedSize];
           buffer.flip();
           buffer.get(result);
           //buffer.Release();
           return result;
        }

        #endregion // Public Methods

        #region Private Methods
        //
        // Private Methods
        //

        private static void CheckPropertyName(string propertyName)
        {
           if ( propertyName == null || propertyName.Length == 0 )
              throw new ArgumentNullException("propertyName");
           CheckIdentifierFormat(propertyName);
        }

        private static void CheckIdentifierFormat(string propertyName)
        {
           //        AMQP Spec: 4.2.5.5 Field Tables
           //        Guidelines for implementers:
           //           * Field names MUST start with a letter, '$' or '#' and may continue with
           //             letters, '$' or '#', digits, or underlines, to a maximum length of 128
           //             characters.
           //           * The server SHOULD validate field names and upon receiving an invalid
           //             field name, it SHOULD signal a connection exception with reply code
           //             503 (syntax error). Conformance test: amq_wlp_table_01.
           //           * A peer MUST handle duplicate fields by using only the first instance.


           // AMQP length limit
           if ( propertyName.Length > 128 )
           {
              throw new ArgumentException("AMQP limits property names to 128 characters");
           }

           // AMQ start character
           if ( !(Char.IsLetter(propertyName[0])
                 || propertyName[0] == '$'
                 || propertyName[0] == '#'
                 || propertyName[0] == '_' ) )// Not official AMQP added for JMS.
           {
              throw new ArgumentException("Identifier '" + propertyName + "' does not start with a valid AMQP start character");
           }
        }

        private object GetObject(string key)
        {
           AMQTypedValue value = GetProperty(key);
           return value != null ? value.Value : null;
        }
        
        private void SetObject(string key, object value)
        {
           if ( value is bool )
           {
              SetBoolean(key, (bool)value);
           } else if ( value is byte )
           {
              SetByte(key, (byte)value);
           } else if ( value is sbyte )
           {
              SetSByte(key, (sbyte)value);
           } else if ( value is short )
           {
              SetInt16(key, (short)value);
           } else if ( value is ushort )
           {
              SetUInt16(key, (ushort)value);
           } else if ( value is int )
           {
              SetInt32(key, (int) value);
           } else if ( value is uint )
           {
              SetUInt32(key, (uint)value);
           } else if ( value is long )
           {
              SetInt64(key, (long) value);
           } else if ( value is ulong )
           {
              SetUInt64(key, (ulong)value);
           } else if ( value is char )
           {
              SetChar(key, (char) value);
           } else if ( value is float )
           {
              SetFloat(key, (float) value);
           } else if ( value is double )
           {
              SetDouble(key, (double) value);
           } else if ( value is decimal )
           {
              SetDecimal(key, (decimal) value);
           } else if ( value is string )
           {
              SetString(key, (string) value);
           } else if ( value is byte[] )
           {
              SetBytes(key, (byte[])value);
           } else
           {
              throw new ArgumentException("Data type not supported yet");
           }
        }
        
        private AMQTypedValue GetProperty(string name)
        {
           lock ( _syncLock )
           {
              if ( _properties == null )
              {
                 if ( _encodedForm == null )
                 {
                    return null;
                 } else
                 {
                    PopulateFromBuffer();
                 }
              }
              return (AMQTypedValue) _properties[name];
           }
        }

        private void PopulateFromBuffer()
        {
           try
           {
              SetFromBuffer(_encodedForm, _encodedSize);
           } catch ( AMQFrameDecodingException e )
           {
              _log.Error("Error decoding FieldTable in deferred decoding mode ", e);
              throw;
           }
        }

        private void SetFromBuffer(ByteBuffer buffer, uint length)
        {
           bool trace = _log.IsDebugEnabled;
           if ( length > 0 )
           {
              int expectedRemaining = buffer.remaining() - (int)length;
              _properties = new LinkedHashtable();

              do
              {
                 string key = EncodingUtils.ReadShortString(buffer);
                 AMQTypedValue value = AMQTypedValue.ReadFromBuffer(buffer);
                 if ( trace )
                 {
                    _log.Debug(string.Format("FieldTable::PropFieldTable(buffer,{0}): Read type '{1}', key '{2}', value '{3}'", length, value.Type, key, value.Value));
                 }
                 _properties.Add(key, value);

              } while ( buffer.remaining() > expectedRemaining );
              _encodedSize = length;
           }
           if ( trace )
           {
              _log.Debug("FieldTable::FieldTable(buffer," + length + "): Done.");
           }
        }

        private void InitMapIfNecessary()
        {
           lock ( _syncLock )
           {
              if ( _properties == null )
              {
                 if ( _encodedForm == null )
                 {
                    _properties = new LinkedHashtable();
                 } else
                 {
                    PopulateFromBuffer();
                 }
              }
           }
        }

        private AMQTypedValue SetProperty(string key, AMQTypedValue value)
        {
           InitMapIfNecessary();
           _encodedForm = null;
           if ( value == null )
           {
              RemoveKey(key);
           }
           AMQTypedValue oldVal = (AMQTypedValue)_properties[key];
           _properties.Add(key, value);
           if ( oldVal != null )
           {
              _encodedSize -= oldVal.EncodingLength;
           } else
           {
              _encodedSize += EncodingUtils.EncodedShortStringLength(key) + (uint)1;
           }
           if ( value != null )
           {
              _encodedSize += value.EncodingLength;
           }

           return oldVal;
        }

        public void WritePayload(ByteBuffer buffer)
        {
           if ( _encodedForm != null )
           {
              buffer.put(_encodedForm);
           } else if ( _properties != null )
           {
              foreach ( DictionaryEntry de in _properties )
              {
                 string key = (string)de.Key;
                 AMQTypedValue value = (AMQTypedValue)de.Value;
                 try
                 {
                    if ( _log.IsDebugEnabled )
                    {
                       _log.Debug("Writing Property:" + key +
                                  " Type:" + value.Type +
                                  " Value:" + value.Value);
                       _log.Debug("Buffer Position:" + buffer.position() +
                                  " Remaining:" + buffer.remaining());
                    }
                    //Write the actual parameter name
                    EncodingUtils.WriteShortStringBytes(buffer, key);
                    value.WriteToBuffer(buffer);
                 } catch ( Exception ex )
                 {
                    if ( _log.IsDebugEnabled )
                    {
                       _log.Debug("Exception thrown:" + ex);
                       _log.Debug("Writing Property:" + key +
                                  " Type:" + value.Type +
                                  " Value:" + value.Value);
                       _log.Debug("Buffer Position:" + buffer.position() +
                                  " Remaining:" + buffer.remaining());
                    }
                 }
              }
           }
        }
        #endregion // Private Methods
    }
}
