/*
 * 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;

namespace Apache.NMS.Stomp.Commands
{
    public class MessageId : BaseDataStructure
    {
        ProducerId producerId;
        long producerSequenceId;
        long brokerSequenceId;

        private string key = null;

        public MessageId() : base()
        {
        }

        public MessageId(ProducerId producerId, long producerSequenceId) : base()
        {
            this.producerId = producerId;
            this.producerSequenceId = producerSequenceId;
        }

        public MessageId(string value) : base()
        {
            this.SetValue(value);
        }

        ///
        /// <summery>
        ///  Get the unique identifier that this object and its own
        ///  Marshaler share.
        /// </summery>
        ///
        public override byte GetDataStructureType()
        {
            return DataStructureTypes.MessageIdType;
        }

        ///
        /// <summery>
        ///  Returns a string containing the information for this DataStructure
        ///  such as its type and value of its elements.
        /// </summery>
        ///
        public override string ToString()
        {
            if( key == null )
            {
                key = producerId.ToString() + ":" + producerSequenceId;
            }

            return key;
        }

        /// <summary>
        /// Sets the value as a String
        /// </summary>
        public void SetValue(string messageKey)
        {
            this.key = messageKey;

            // Parse off the sequenceId
            int p = messageKey.LastIndexOf(":");
            if(p >= 0)
            {
                producerSequenceId = Int64.Parse(messageKey.Substring(p + 1));
                messageKey = messageKey.Substring(0, p);
            }
            producerId = new ProducerId(messageKey);
        }

        public ProducerId ProducerId
        {
            get { return producerId; }
            set { this.producerId = value; }
        }

        public long ProducerSequenceId
        {
            get { return producerSequenceId; }
            set { this.producerSequenceId = value; }
        }

        public long BrokerSequenceId
        {
            get { return brokerSequenceId; }
            set { this.brokerSequenceId = value; }
        }

        public override int GetHashCode()
        {
            int answer = 0;

            answer = (answer * 37) + HashCode(ProducerId);
            answer = (answer * 37) + HashCode(ProducerSequenceId);
            answer = (answer * 37) + HashCode(BrokerSequenceId);

            return answer;
        }

        public override bool Equals(object that)
        {
            if(that is MessageId)
            {
                return Equals((MessageId) that);
            }
            return false;
        }

        public virtual bool Equals(MessageId that)
        {
            if(!Equals(this.ProducerId, that.ProducerId))
            {
                return false;
            }
            if(!Equals(this.ProducerSequenceId, that.ProducerSequenceId))
            {
                return false;
            }
            if(!Equals(this.BrokerSequenceId, that.BrokerSequenceId))
            {
                return false;
            }

            return true;
        }
    };
}

