﻿/*
 * 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.Threading.Tasks;
using Apache.NMS.AMQP.Message.Facade;
using Apache.NMS.AMQP.Util.Synchronization;
using Apache.NMS.Util;

namespace Apache.NMS.AMQP.Message
{
    public class NmsMessage : IMessage
    {
        private MessagePropertyIntercepter properties;
        private bool readOnlyProperties;

        public NmsMessage(INmsMessageFacade facade)
        {
            Facade = facade;
        }

        public INmsMessageFacade Facade { get; }

        public IPrimitiveMap Properties => properties ??
                                           (properties = new MessagePropertyIntercepter(this, Facade.Properties,
                                               IsReadOnlyProperties));

        public string NMSCorrelationID
        {
            get => Facade.NMSCorrelationID;
            set => Facade.NMSCorrelationID = value;
        }

        public IDestination NMSDestination
        {
            get => Facade.NMSDestination;
            set => Facade.NMSDestination = value;
        }

        public TimeSpan NMSTimeToLive
        {
            get => Facade.NMSTimeToLive;
            set => Facade.NMSTimeToLive = value;
        }

        public string NMSMessageId
        {
            get => Facade.NMSMessageId;
            set => Facade.NMSMessageId = value;
        }

        public MsgDeliveryMode NMSDeliveryMode
        {
            get => Facade.IsPersistent ? MsgDeliveryMode.Persistent : MsgDeliveryMode.NonPersistent;
            set
            {
                CheckReadOnly();
                switch (value)
                {
                    case MsgDeliveryMode.Persistent:
                        Facade.IsPersistent = true;
                        break;
                    case MsgDeliveryMode.NonPersistent:
                        Facade.IsPersistent = false;
                        break;
                    default:
                        throw new NMSException($"Invalid DeliveryMode specified: {value}");
                }
            }
        }

        public MsgPriority NMSPriority
        {
            get => Facade.NMSPriority;
            set => Facade.NMSPriority = value;
        }

        public bool NMSRedelivered
        {
            get => Facade.NMSRedelivered;
            set => Facade.NMSRedelivered = value;
        }

        public IDestination NMSReplyTo
        {
            get => Facade.NMSReplyTo;
            set => Facade.NMSReplyTo = value;
        }

        public DateTime NMSTimestamp
        {
            get => Facade.NMSTimestamp;
            set => Facade.NMSTimestamp = value;
        }

        public string NMSType
        {
            get => Facade.NMSType;
            set => Facade.NMSType = value;
        }

        public DateTime NMSDeliveryTime
        {
            get => Facade.DeliveryTime;
            set => Facade.DeliveryTime = value;
        }

        public string NMSXGroupId
        {
            get => Facade.GroupId;
            set => Facade.GroupId = value;
        }

        public int NMSXGroupSeq
        {
            get => (int) Facade.GroupSequence;
            set => Facade.GroupSequence = (uint) value;
        }

        public NmsAcknowledgeCallback NmsAcknowledgeCallback { get; set; }

        public virtual bool IsReadOnly { get; set; }

        public bool IsReadOnlyBody { get; set; }

        public bool IsReadOnlyProperties
        {
            get => readOnlyProperties;
            set
            {
                readOnlyProperties = value;
                if (properties != null)
                {
                    properties.ReadOnly = value;
                }
            }
        }

        public void Acknowledge()
        {
            AcknowledgeAsync().GetAsyncResult();
        }

        public async Task AcknowledgeAsync()
        {
            if (NmsAcknowledgeCallback != null)
            {
                try
                {
                    await NmsAcknowledgeCallback.Acknowledge().Await();
                    NmsAcknowledgeCallback = null;
                }
                catch (Exception e)
                {
                    throw NMSExceptionSupport.Create(e);
                }
            }
        }

        public virtual void ClearBody()
        {
            CheckReadOnly();
            IsReadOnlyBody = false;
            Facade.ClearBody();
        }

        public void ClearProperties()
        {
            CheckReadOnly();
            IsReadOnlyProperties = false;
            Properties.Clear();
        }

        public virtual void OnSend(TimeSpan producerTtl)
        {
            IsReadOnly = true;
            Facade.OnSend(producerTtl);
        }

        public void OnDispatch()
        {
            IsReadOnly = false;
            IsReadOnlyBody = true;
            IsReadOnlyProperties = true;
        }

        public override string ToString()
        {
            return $"NmsMessage {{ {Facade} }}";
        }

        protected bool Equals(NmsMessage other)
        {
            if (other.NMSMessageId == null)
                return false;

            return string.Equals(NMSMessageId, other.NMSMessageId);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((NmsMessage) obj);
        }

        public override int GetHashCode()
        {
            return (NMSMessageId != null ? NMSMessageId.GetHashCode() : base.GetHashCode());
        }

        //----- State validation methods -----------------------------------------//

        protected void CheckReadOnly()
        {
            if (IsReadOnly)
            {
                throw new MessageNotReadableException("Message is currently read-only");
            }
        }

        protected void CheckWriteOnlyBody()
        {
            if (!IsReadOnlyBody)
            {
                throw new MessageNotReadableException("Message body is write-only");
            }
        }

        protected void CheckReadOnlyBody()
        {
            if (IsReadOnly || IsReadOnlyBody)
            {
                throw new MessageNotWriteableException("Message body is read-only");
            }
        }

        public bool IsExpired()
        {
            DateTime? expireTime = Facade.Expiration;
            return expireTime != null && DateTime.UtcNow > expireTime;
        }

        public virtual NmsMessage Copy()
        {
            NmsMessage copy = new NmsMessage(Facade.Copy());
            CopyInto(copy);
            return copy;
        }

        protected void CopyInto(NmsMessage target)
        {
            target.IsReadOnly = IsReadOnly;
            target.IsReadOnlyBody = IsReadOnlyBody;
            target.IsReadOnlyProperties = IsReadOnlyProperties;
            target.NmsAcknowledgeCallback = NmsAcknowledgeCallback;
        }

        public virtual bool IsBodyAssignableTo(Type type)
        {
            return true;
        }

        public T Body<T>()
        {
            if (IsBodyAssignableTo(typeof(T)))
            {
                return DoGetBody<T>();
            }

            throw new MessageFormatException("Message body cannot be read as type: " + typeof(T));
        }

        protected virtual T DoGetBody<T>()
        {
            return default;
        }
    }
}