﻿/*
 * 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.Collections;
using Amqp.Framing;
using Amqp.Types;
using Apache.NMS.AMQP.Message;
using Apache.NMS.AMQP.Message.Facade;
using Apache.NMS.AMQP.Util;
using Apache.NMS.Util;

namespace Apache.NMS.AMQP.Provider.Amqp.Message
{
    public class AmqpNmsStreamMessageFacade : AmqpNmsMessageFacade, INmsStreamMessageFacade
    {
        private IList list;
        private int position = 0;
        
        public override sbyte? JmsMsgType => MessageSupport.JMS_TYPE_STRM;

        public object Peek()
        {
            if (IsEmpty || position >= list.Count)
            {
                throw new MessageEOFException("Attempt to read past end of stream");
            }

            object value = list[position];
            if (value is byte[] binary)
            {
                // Copy to a byte[], ensure we copy only the required portion.
                byte[] bin = new byte[binary.Length];
                binary.CopyTo(bin, 0);
                value = bin;
            }

            return value;
        }

        private bool IsEmpty => list.Count <= 0;

        public void Pop()
        {
            if (IsEmpty || position >= list.Count)
            {
                throw new MessageEOFException("Attempt to read past end of stream");
            }

            position++;
        }

        public void Reset()
        {
            position = 0;
        }

        public void Put(object value)
        {
            object entry = value;
            if (entry != null && entry is byte[] bytes)
            {
                byte[] bin = new byte[bytes.Length];
                bytes.CopyTo(bin, 0);
                entry = bin;
            }
            if (list.Add(entry) < 0)
            {
                throw NMSExceptionSupport.Create($"Failed to add {entry.ToString()} to stream.", null);
            }
        }

        public sbyte JmsMessageType => MessageSupport.JMS_TYPE_STRM;

        protected override void InitializeBody()
        {
            if (Message.BodySection == null)
            {
                list = InitializeEmptyBody(true);
            }
            else if (Message.BodySection is AmqpSequence amqpSequence)
            {
                list = amqpSequence.List ?? InitializeEmptyBody(true);
            }
            else if (Message.BodySection is AmqpValue amqpValue)
            {
                object value = amqpValue.Value;
                if (value == null)
                {
                    list = InitializeEmptyBody(false);
                }
                else if (value is IList valueList)
                {
                    list = valueList;
                }
                else
                {
                    throw new IllegalStateException($"Unexpected amqp-value body content type: {value.GetType().Name}");
                }
            }
            else
            {
                throw new IllegalStateException($"Unexpected message body type: {Message.BodySection.GetType().Name}");
            }
        }

        protected override void InitializeEmptyBody()
        {
            base.InitializeEmptyBody();
            list = InitializeEmptyBody(true);
        }

        private List InitializeEmptyBody(bool useSequenceBody)
        {
            List emptyList = new List();
            if (useSequenceBody)
            {
                Message.BodySection = new AmqpSequence {List = emptyList};
            }
            else
            {
                Message.BodySection = new AmqpValue {Value = emptyList};
            }

            return emptyList;
        }

        public override bool HasBody() => !IsEmpty;

        public override void ClearBody()
        {
            list.Clear();
            position = 0;
        }

        public override NmsMessage AsMessage()
        {
            return new NmsStreamMessage(this);
        }

        public override INmsMessageFacade Copy()
        {
            AmqpNmsStreamMessageFacade copy = new AmqpNmsStreamMessageFacade();
            CopyInto(copy);
            return copy;
        }
    }
}