﻿/*
 * 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 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 AmqpNmsBytesMessageFacade : AmqpNmsMessageFacade, INmsBytesMessageFacade
    {
        private EndianBinaryReader byteIn = null;
        private EndianBinaryWriter byteOut = null;

        private static readonly Data EMPTY_DATA = new Data { Binary = new byte[0] };

        public override sbyte JmsMsgType => MessageSupport.JMS_TYPE_BYTE;
        public long BodyLength => GetBinaryFromBody().Binary.LongLength;

        public BinaryReader GetDataReader()
        {
            if (byteOut != null)
            {
                throw new IllegalStateException("Body is being written to, cannot perform a read.");
            }

            if (byteIn == null)
            {
                Data body = GetBinaryFromBody();
                Stream dataStream = new MemoryStream(body.Binary, false);
                byteIn = new EndianBinaryReader(dataStream);
            }

            return byteIn;
        }

        private Data GetBinaryFromBody()
        {
            RestrictedDescribed body = Message.BodySection;
            Data result = EMPTY_DATA;
            if (body == null)
            {
                return result;
            }
            else if (body is Data)
            {
                byte[] binary = (body as Data).Binary;
                if (binary != null && binary.Length != 0)
                {
                    return body as Data;
                }
            }
            else if (body is AmqpValue)
            {
                object value = (body as AmqpValue).Value;
                if (value == null)
                {
                    return result;
                }

                if (value is byte[])
                {
                    byte[] dataValue = value as byte[];
                    if (dataValue.Length > 0)
                    {
                        result = new Data();
                        result.Binary = dataValue;
                    }
                }
                else
                {
                    throw new IllegalStateException("Unexpected Amqp value content-type: " + value.GetType().FullName);
                }
            }
            else
            {
                throw new IllegalStateException("Unexpected body content-type: " + body.GetType().FullName);
            }

            return result;
        }

        public BinaryWriter GetDataWriter()
        {
            if (byteIn != null)
            {
                throw new IllegalStateException("Body is being read from, cannot perform a write.");
            }

            if (byteOut == null)
            {
                MemoryStream outputBuffer = new MemoryStream();
                byteOut = new EndianBinaryWriter(outputBuffer);
                Message.BodySection = EMPTY_DATA;
            }

            return byteOut;
        }

        protected override void InitializeEmptyBody()
        {
            ContentType = SymbolUtil.OCTET_STREAM_CONTENT_TYPE;
            Message.BodySection = EMPTY_DATA;
        }

        public void Reset()
        {
            if (byteOut != null)
            {
                try
                {
                    using (MemoryStream byteStream = new MemoryStream((int) byteOut.BaseStream.Length))
                    {
                        byteOut.BaseStream.Position = 0;
                        byteOut.BaseStream.CopyTo(byteStream);

                        byte[] value = byteStream.ToArray();
                        Message.BodySection = new Data() { Binary = value };
                    }
                }
                finally
                {
                    byteOut.Dispose();
                    byteOut = null;
                }

            }

            if (byteIn != null)
            {
                byteIn.Dispose();
                byteIn = null;
            }
        }

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

        public override void ClearBody()
        {
            Reset();
            Message.BodySection = EMPTY_DATA;
        }

        public override bool HasBody()
        {
            if (byteOut != null)
                return byteOut.BaseStream.Length > 0;

            return BodyLength > 0;
        }

        public override void OnSend(TimeSpan producerTtl)
        {
            base.OnSend(producerTtl);

            Reset();
        }

        public override INmsMessageFacade Copy()
        {
            Reset();
            AmqpNmsBytesMessageFacade copy = new AmqpNmsBytesMessageFacade();
            CopyInto(copy);

            if (!copy.HasBody())
            {
                copy.Message.BodySection = EMPTY_DATA;
            }

            return copy;
        }
    }
}