/*
*
* 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.IO;
using System.Text;
using org.apache.qpid.transport.util;

namespace org.apache.qpid.transport.network
{
    /// <summary> 
    /// InputHandler
    /// </summary>
    public sealed class InputHandler : Receiver<ReceivedPayload<NetworkEvent>>
    {
        public enum State
        {
            PROTO_HDR,
            FRAME_HDR,
            FRAME_BODY,
            ERROR
        }

        private static readonly Logger log = Logger.get(typeof(InputHandler));
        private readonly Object m_objectLock = new object();

        // the event raised when a buffer is read from the wire        
        public event EventHandler<ReceivedPayload<NetworkEvent>> ReceivedEvent;
        public event EventHandler<ExceptionArgs> ExceptionProcessing;
        public event EventHandler HandlerClosed;

        event EventHandler<ReceivedPayload<NetworkEvent>> Receiver<ReceivedPayload<NetworkEvent>>.Received
        {
            add
            {
                lock (m_objectLock)
                {
                    ReceivedEvent += value;
                }
            }
            remove
            {
                lock (m_objectLock)
                {
                    ReceivedEvent -= value;
                }
            }
        }

        event EventHandler<ExceptionArgs> Receiver<ReceivedPayload<NetworkEvent>>.Exception
        {
            add
            {
                lock (m_objectLock)
                {
                    ExceptionProcessing += value;
                }
            }
            remove
            {
                lock (m_objectLock)
                {
                    ExceptionProcessing -= value;
                }
            }
        }

        event EventHandler Receiver<ReceivedPayload<NetworkEvent>>.Closed
        {
            add
            {
                lock (m_objectLock)
                {
                    HandlerClosed += value;
                }
            }
            remove
            {
                lock (m_objectLock)
                {
                    HandlerClosed -= value;
                }
            }
        }

        private State state;
        private MemoryStream input;
        private int needed;

        private byte flags;
        private SegmentType type;
        private byte track;
        private int channel;

        public InputHandler(State state)
        {
            this.state = state;
            switch (state)
            {
                case State.PROTO_HDR:
                    needed = 8;
                    break;
                case State.FRAME_HDR:
                    needed = Frame.HEADER_SIZE;
                    break;
            }
        }

        // The command listening for a buffer read.  
        public void On_ReceivedBuffer(object sender, ReceivedPayload<MemoryStream> payload)
        {
            MemoryStream buf = payload.Payload;
            int remaining = (int) buf.Length;
            if( input != null )
            {
                remaining += (int) input.Length;
            }
            try
            {
                while (remaining > 0)
                {
                    if (remaining >= needed)
                    {                        
                        if (input != null)
                        {
                            byte[] tmp = new byte[buf.Length];
                            buf.Read(tmp, 0, tmp.Length);
                            input.Write(tmp, 0, tmp.Length);
                            input.Seek(0, SeekOrigin.Begin);
                            buf = input;    
                        }                      
                        int startPos = (int)buf.Position;
                        int consumed = needed;
                        state = next(buf);
                        if ((buf.Position - startPos) < consumed)
                        {
                            buf.Seek(consumed  - (buf.Position - startPos), SeekOrigin.Current);
                        }
                        remaining -= consumed;
                        input = null;                        
                    }
                    else
                    {
                        byte[] tmp;
                        if (input == null)
                        {
                            input = new MemoryStream();
                            tmp = new byte[remaining];                            
                        }
                        else
                        {
                            // this is a full buffer 
                            tmp = new byte[buf.Length];
                        }
                        buf.Read(tmp, 0, tmp.Length);
                        input.Write(tmp, 0, tmp.Length);
                        remaining = 0;
                    }
                }
            }
            catch (Exception t)
            {
                Console.Write(t);
                if (ExceptionProcessing != null)
                {
                    ExceptionProcessing(this, new ExceptionArgs(t));
                }
            }
        }

        #region Private Support Functions

        private State next(MemoryStream buf)
        {
            BinaryReader reader = new BinaryReader(buf);

            switch (state)
            {
                case State.PROTO_HDR:
                    char a = reader.ReadChar();
                    char m = reader.ReadChar();
                    char q = reader.ReadChar();
                    char p = reader.ReadChar();
                    if (a != 'A' &&
                        m != 'M' &&
                        q != 'Q' &&
                        p != 'P')
                    {
                        Error("bad protocol header: {0}", buf.ToString());
                        return State.ERROR;
                    }
                    reader.ReadByte(); 
                    byte instance = reader.ReadByte();
                    byte major = reader.ReadByte();
                    byte minor = reader.ReadByte();
                    Fire_NetworkEvent(new ProtocolHeader(instance, major, minor));                    
                    needed = Frame.HEADER_SIZE;
                    return State.FRAME_HDR;
                case State.FRAME_HDR:
                    reader = new BinaryReader(buf, Encoding.BigEndianUnicode);
                    flags = reader.ReadByte();
                    type = SegmentTypeGetter.get(reader.ReadByte()); // generated code 
                    int size =  reader.ReadUInt16();
                    size = ByteEncoder.GetBigEndian((UInt16)size);                    
                    size -= Frame.HEADER_SIZE;
                    if (size < 0 || size > (64 * 1024 - 12))
                    {
                        Error("bad frame size: {0:d}", size);
                        return State.ERROR;
                    }
                    reader.ReadByte();
                    byte b = reader.ReadByte();
                    if ((b & 0xF0) != 0)
                    {
                        Error("non-zero reserved bits in upper nibble of " +
                              "frame header byte 5: {0}", b);
                        return State.ERROR;
                    }
                    track = (byte)(b & 0xF);
                    channel = reader.ReadUInt16();
                    channel = ByteEncoder.GetBigEndian((UInt16)channel);  
                    if (size == 0)
                    {
                        Fire_NetworkEvent(new Frame(flags, type, track, channel, 0, new MemoryStream()));                  
                        needed = Frame.HEADER_SIZE;
                        return State.FRAME_HDR;
                    }
                    needed = size;
                    return State.FRAME_BODY;
                case State.FRAME_BODY:                                       
                    Fire_NetworkEvent(new Frame(flags, type, track, channel, needed, buf));                  
                    needed = Frame.HEADER_SIZE;
                    return State.FRAME_HDR;
                default:
                    if (ExceptionProcessing != null)
                    {
                        ExceptionProcessing(this, new ExceptionArgs(new Exception("Error creating frame")));
                    }
                    throw new Exception("Error creating frame");
            }
        }
        
        private void Error(String fmt, params Object[] args)
        {
            Fire_NetworkEvent(new ProtocolError(Frame.L1, fmt, args));            
        }

        private void Fire_NetworkEvent(NetworkEvent netevent)
        {
            log.debug("InputHandler: network event:", netevent);
            ReceivedPayload<NetworkEvent> payload = new ReceivedPayload<NetworkEvent>();
            payload.Payload = netevent;
            if (ReceivedEvent != null)
            {
                ReceivedEvent(this, payload);
            }
            else
            {
                log.debug("Nobody listening for event: {0}");
            }
        }

        #endregion
    }
}