using System;
using System.Collections.Generic;
using Google.ProtocolBuffers.Descriptors;

//Disable CS3011: only CLS-compliant members can be abstract
#pragma warning disable 3011

namespace Google.ProtocolBuffers.Serialization
{
    /// <summary>
    /// Provides a base-class that provides some basic functionality for handling type dispatching
    /// </summary>
    public abstract class AbstractReader : ICodedInputStream
    {
        private const int MaxDepth = CodedInputStream.DefaultRecursionLimit;
        protected int Depth;

        /// <summary>
        /// Merges the contents of stream into the provided message builder
        /// </summary>
        public TBuilder Merge<TBuilder>(TBuilder builder) where TBuilder : IBuilderLite
        {
            return Merge(builder, ExtensionRegistry.Empty);
        }

        /// <summary>
        /// Merges the contents of stream into the provided message builder
        /// </summary>
        public abstract TBuilder Merge<TBuilder>(TBuilder builder, ExtensionRegistry registry)
            where TBuilder : IBuilderLite;

        /// <summary>
        /// Peeks at the next field in the input stream and returns what information is available.
        /// </summary>
        /// <remarks>
        /// This may be called multiple times without actually reading the field.  Only after the field
        /// is either read, or skipped, should PeekNext return a different value.
        /// </remarks>
        protected abstract bool PeekNext(out string field);

        /// <summary>
        /// Causes the reader to skip past this field
        /// </summary>
        protected abstract void Skip();

        /// <summary>
        /// Returns true if it was able to read a Boolean from the input
        /// </summary>
        protected abstract bool Read(ref bool value);

        /// <summary>
        /// Returns true if it was able to read a Int32 from the input
        /// </summary>
        protected abstract bool Read(ref int value);

        /// <summary>
        /// Returns true if it was able to read a UInt32 from the input
        /// </summary>
        [CLSCompliant(false)]
        protected abstract bool Read(ref uint value);

        /// <summary>
        /// Returns true if it was able to read a Int64 from the input
        /// </summary>
        protected abstract bool Read(ref long value);

        /// <summary>
        /// Returns true if it was able to read a UInt64 from the input
        /// </summary>
        [CLSCompliant(false)]
        protected abstract bool Read(ref ulong value);

        /// <summary>
        /// Returns true if it was able to read a Single from the input
        /// </summary>
        protected abstract bool Read(ref float value);

        /// <summary>
        /// Returns true if it was able to read a Double from the input
        /// </summary>
        protected abstract bool Read(ref double value);

        /// <summary>
        /// Returns true if it was able to read a String from the input
        /// </summary>
        protected abstract bool Read(ref string value);

        /// <summary>
        /// Returns true if it was able to read a ByteString from the input
        /// </summary>
        protected abstract bool Read(ref ByteString value);

        /// <summary>
        /// returns true if it was able to read a single value into the value reference.  The value
        /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap.
        /// </summary>
        protected abstract bool ReadEnum(ref object value);

        /// <summary>
        /// Merges the input stream into the provided IBuilderLite 
        /// </summary>
        protected abstract bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry);

        /// <summary>
        /// Merges the input stream into the provided IBuilderLite 
        /// </summary>
        public virtual bool ReadGroup(IBuilderLite value, ExtensionRegistry registry)
        {
            return ReadMessage(value, registry);
        }

        /// <summary>
        /// Cursors through the array elements and stops at the end of the array
        /// </summary>
        protected virtual IEnumerable<string> ForeachArrayItem(string field)
        {
            string next = field;
            while (true)
            {
                yield return next;

                if (!PeekNext(out next) || next != field)
                {
                    break;
                }
            }
        }

        /// <summary>
        /// Reads an array of T messages
        /// </summary>
        public virtual bool ReadMessageArray<T>(string field, ICollection<T> items, IMessageLite messageType,
                                                ExtensionRegistry registry)
        {
            bool success = false;
            foreach (string next in ForeachArrayItem(field))
            {
                IBuilderLite builder = messageType.WeakCreateBuilderForType();
                if (ReadMessage(builder, registry))
                {
                    items.Add((T) builder.WeakBuild());
                    success |= true;
                }
            }
            return success;
        }

        /// <summary>
        /// Reads an array of T messages as a proto-buffer group
        /// </summary>
        public virtual bool ReadGroupArray<T>(string field, ICollection<T> items, IMessageLite messageType,
                                              ExtensionRegistry registry)
        {
            bool success = false;
            foreach (string next in ForeachArrayItem(field))
            {
                IBuilderLite builder = messageType.WeakCreateBuilderForType();
                if (ReadGroup(builder, registry))
                {
                    items.Add((T) builder.WeakBuild());
                    success |= true;
                }
            }
            return success;
        }

        /// <summary>
        /// Reads an array of System.Enum type T and adds them to the collection
        /// </summary>
        public virtual bool ReadEnumArray(string field, ICollection<object> items)
        {
            bool success = false;
            foreach (string next in ForeachArrayItem(field))
            {
                object temp = null;
                if (ReadEnum(ref temp))
                {
                    items.Add(temp);
                    success |= true;
                }
            }
            return success;
        }

        /// <summary>
        /// Reads an array of T, where T is a primitive type defined by FieldType
        /// </summary>
        public virtual bool ReadArray<T>(FieldType type, string field, ICollection<T> items)
        {
            bool success = false;
            foreach (string next in ForeachArrayItem(field))
            {
                object temp = null;
                if (ReadField(type, ref temp))
                {
                    items.Add((T) temp);
                    success |= true;
                }
            }
            return success;
        }

        /// <summary>
        /// returns true if it was able to read a single primitive value of FieldType into the value reference
        /// </summary>
        public virtual bool ReadField(FieldType type, ref object value)
        {
            switch (type)
            {
                case FieldType.Bool:
                    {
                        bool temp = false;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.Int64:
                case FieldType.SInt64:
                case FieldType.SFixed64:
                    {
                        long temp = 0;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.UInt64:
                case FieldType.Fixed64:
                    {
                        ulong temp = 0;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.Int32:
                case FieldType.SInt32:
                case FieldType.SFixed32:
                    {
                        int temp = 0;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.UInt32:
                case FieldType.Fixed32:
                    {
                        uint temp = 0;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.Float:
                    {
                        float temp = float.NaN;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.Double:
                    {
                        double temp = float.NaN;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.String:
                    {
                        string temp = null;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                case FieldType.Bytes:
                    {
                        ByteString temp = null;
                        if (Read(ref temp))
                        {
                            value = temp;
                        }
                        else
                        {
                            return false;
                        }
                        break;
                    }
                default:
                    throw InvalidProtocolBufferException.InvalidTag();
            }
            return true;
        }

        #region ICodedInputStream Members

        bool ICodedInputStream.ReadTag(out uint fieldTag, out string fieldName)
        {
            fieldTag = 0;
            if (PeekNext(out fieldName))
            {
                return true;
            }
            return false;
        }

        bool ICodedInputStream.ReadDouble(ref double value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadFloat(ref float value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadUInt64(ref ulong value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadInt64(ref long value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadInt32(ref int value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadFixed64(ref ulong value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadFixed32(ref uint value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadBool(ref bool value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadString(ref string value)
        {
            return Read(ref value);
        }

        void ICodedInputStream.ReadGroup(int fieldNumber, IBuilderLite builder, ExtensionRegistry extensionRegistry)
        {
            if (Depth++ > MaxDepth)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ReadGroup(builder, extensionRegistry);
            Depth--;
        }

        void ICodedInputStream.ReadUnknownGroup(int fieldNumber, IBuilderLite builder)
        {
            throw new NotSupportedException();
        }

        void ICodedInputStream.ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry)
        {
            if (Depth++ > MaxDepth)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ReadMessage(builder, extensionRegistry);
            Depth--;
        }

        bool ICodedInputStream.ReadBytes(ref ByteString value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadUInt32(ref uint value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadEnum(ref IEnumLite value, out object unknown, IEnumLiteMap mapping)
        {
            value = null;
            unknown = null;
            if (ReadEnum(ref unknown))
            {
                if (unknown is int)
                {
                    value = mapping.FindValueByNumber((int) unknown);
                }
                else if (unknown is string)
                {
                    value = mapping.FindValueByName((string) unknown);
                }
                return value != null;
            }
            return false;
        }

        bool ICodedInputStream.ReadEnum<T>(ref T value, out object rawValue)
        {
            rawValue = null;
            if (ReadEnum(ref rawValue))
            {
                if (Enum.IsDefined(typeof (T), rawValue))
                {
                    if (rawValue is int)
                    {
                        value = (T) rawValue;
                    }
                    else if (rawValue is string)
                    {
                        value = (T) Enum.Parse(typeof (T), (string) rawValue, false);
                    }
                    else
                    {
                        value = default(T);
                        return false;
                    }
                    return true;
                }
            }
            return false;
        }

        bool ICodedInputStream.ReadSFixed32(ref int value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadSFixed64(ref long value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadSInt32(ref int value)
        {
            return Read(ref value);
        }

        bool ICodedInputStream.ReadSInt64(ref long value)
        {
            return Read(ref value);
        }

        void ICodedInputStream.ReadPrimitiveArray(FieldType fieldType, uint fieldTag, string fieldName,
                                                  ICollection<object> list)
        {
            ReadArray(fieldType, fieldName, list);
        }

        void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection<IEnumLite> list,
                                             out ICollection<object> unknown, IEnumLiteMap mapping)
        {
            unknown = null;
            List<object> array = new List<object>();
            if (ReadEnumArray(fieldName, array))
            {
                foreach (object rawValue in array)
                {
                    IEnumLite item = null;
                    if (rawValue is int)
                    {
                        item = mapping.FindValueByNumber((int) rawValue);
                    }
                    else if (rawValue is string)
                    {
                        item = mapping.FindValueByName((string) rawValue);
                    }

                    if (item != null)
                    {
                        list.Add(item);
                    }
                    else
                    {
                        if (unknown == null)
                        {
                            unknown = new List<object>();
                        }
                        unknown.Add(rawValue);
                    }
                }
            }
        }

        void ICodedInputStream.ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list,
                                                out ICollection<object> unknown)
        {
            unknown = null;
            List<object> array = new List<object>();
            if (ReadEnumArray(fieldName, array))
            {
                foreach (object rawValue in array)
                {
                    if (rawValue is int)
                    {
                        list.Add((T) rawValue);
                    }
                    else if (rawValue is string)
                    {
                        list.Add((T) Enum.Parse(typeof (T), (string) rawValue, false));
                    }
                    else
                    {
                        if (unknown == null)
                        {
                            unknown = new List<object>();
                        }
                        unknown.Add(rawValue);
                    }
                }
            }
        }

        void ICodedInputStream.ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType,
                                                   ExtensionRegistry registry)
        {
            if (Depth++ > MaxDepth)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ReadMessageArray(fieldName, list, messageType, registry);
            Depth--;
        }

        void ICodedInputStream.ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType,
                                                 ExtensionRegistry registry)
        {
            if (Depth++ > MaxDepth)
            {
                throw InvalidProtocolBufferException.RecursionLimitExceeded();
            }
            ReadGroupArray(fieldName, list, messageType, registry);
            Depth--;
        }

        bool ICodedInputStream.ReadPrimitiveField(FieldType fieldType, ref object value)
        {
            return ReadField(fieldType, ref value);
        }

        bool ICodedInputStream.IsAtEnd
        {
            get
            {
                string next;
                return PeekNext(out next) == false;
            }
        }

        bool ICodedInputStream.SkipField()
        {
            Skip();
            return true;
        }

        void ICodedInputStream.ReadStringArray(uint fieldTag, string fieldName, ICollection<string> list)
        {
            ReadArray(FieldType.String, fieldName, list);
        }

        void ICodedInputStream.ReadBytesArray(uint fieldTag, string fieldName, ICollection<ByteString> list)
        {
            ReadArray(FieldType.Bytes, fieldName, list);
        }

        void ICodedInputStream.ReadBoolArray(uint fieldTag, string fieldName, ICollection<bool> list)
        {
            ReadArray(FieldType.Bool, fieldName, list);
        }

        void ICodedInputStream.ReadInt32Array(uint fieldTag, string fieldName, ICollection<int> list)
        {
            ReadArray(FieldType.Int32, fieldName, list);
        }

        void ICodedInputStream.ReadSInt32Array(uint fieldTag, string fieldName, ICollection<int> list)
        {
            ReadArray(FieldType.SInt32, fieldName, list);
        }

        void ICodedInputStream.ReadUInt32Array(uint fieldTag, string fieldName, ICollection<uint> list)
        {
            ReadArray(FieldType.UInt32, fieldName, list);
        }

        void ICodedInputStream.ReadFixed32Array(uint fieldTag, string fieldName, ICollection<uint> list)
        {
            ReadArray(FieldType.Fixed32, fieldName, list);
        }

        void ICodedInputStream.ReadSFixed32Array(uint fieldTag, string fieldName, ICollection<int> list)
        {
            ReadArray(FieldType.SFixed32, fieldName, list);
        }

        void ICodedInputStream.ReadInt64Array(uint fieldTag, string fieldName, ICollection<long> list)
        {
            ReadArray(FieldType.Int64, fieldName, list);
        }

        void ICodedInputStream.ReadSInt64Array(uint fieldTag, string fieldName, ICollection<long> list)
        {
            ReadArray(FieldType.SInt64, fieldName, list);
        }

        void ICodedInputStream.ReadUInt64Array(uint fieldTag, string fieldName, ICollection<ulong> list)
        {
            ReadArray(FieldType.UInt64, fieldName, list);
        }

        void ICodedInputStream.ReadFixed64Array(uint fieldTag, string fieldName, ICollection<ulong> list)
        {
            ReadArray(FieldType.Fixed64, fieldName, list);
        }

        void ICodedInputStream.ReadSFixed64Array(uint fieldTag, string fieldName, ICollection<long> list)
        {
            ReadArray(FieldType.SFixed64, fieldName, list);
        }

        void ICodedInputStream.ReadDoubleArray(uint fieldTag, string fieldName, ICollection<double> list)
        {
            ReadArray(FieldType.Double, fieldName, list);
        }

        void ICodedInputStream.ReadFloatArray(uint fieldTag, string fieldName, ICollection<float> list)
        {
            ReadArray(FieldType.Float, fieldName, list);
        }

        #endregion
    }
}