/**
 * 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.
 */
package org.apache.activemq.openwire.commands;

import org.apache.activemq.openwire.annotations.OpenWireType;
import org.apache.activemq.openwire.annotations.OpenWireExtension;
import org.apache.activemq.openwire.annotations.OpenWireProperty;

/**
 * @openwire:marshaller code="110"
 */
@OpenWireType(typeCode = 110)
public class MessageId implements DataStructure, Comparable<MessageId> {

    public static final byte DATA_STRUCTURE_TYPE = CommandTypes.MESSAGE_ID;

    @OpenWireProperty(version = 10, sequence = 1)
    protected String textView;

    @OpenWireProperty(version = 1, sequence = 2, cached = true)
    protected ProducerId producerId;

    @OpenWireProperty(version = 1, sequence = 3)
    protected long producerSequenceId;

    @OpenWireProperty(version = 1, sequence = 4)
    protected long brokerSequenceId;

    @OpenWireExtension
    private transient String key;

    @OpenWireExtension
    private transient int hashCode;

    public MessageId() {
        this.producerId = new ProducerId();
    }

    public MessageId(ProducerInfo producerInfo, long producerSequenceId) {
        this.producerId = producerInfo.getProducerId();
        this.producerSequenceId = producerSequenceId;
    }

    public MessageId(String messageKey) {
        setValue(messageKey);
    }

    public MessageId(String producerId, long producerSequenceId) {
        this(new ProducerId(producerId), producerSequenceId);
    }

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

    /**
     * Sets the value as a String
     */
    public void setValue(String messageKey) {
        key = messageKey;
        // Parse off the sequenceId
        int p = messageKey.lastIndexOf(":");
        if (p >= 0) {
            producerSequenceId = Long.parseLong(messageKey.substring(p + 1));
            messageKey = messageKey.substring(0, p);
        } else {
            throw new NumberFormatException();
        }
        producerId = new ProducerId(messageKey);
    }

    /**
     * Sets the transient text view of the message which will be ignored if the message is marshaled on a transport; so
     * is only for in-JVM changes to accommodate foreign JMS message IDs
     */
    public void setTextView(String key) {
        this.textView = key;
    }

    /**
     * @openwire:property version=10
     * @return
     */
    public String getTextView() {
        return textView;
    }

    @Override
    public byte getDataStructureType() {
        return DATA_STRUCTURE_TYPE;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || o.getClass() != getClass()) {
            return false;
        }

        MessageId id = (MessageId) o;
        return producerSequenceId == id.producerSequenceId && producerId.equals(id.producerId);
    }

    @Override
    public int hashCode() {
        if (hashCode == 0) {
            if (textView != null) {
                hashCode = textView.hashCode();
            } else {
                hashCode = producerId.hashCode() ^ (int) producerSequenceId;
            }
        }
        return hashCode;
    }

    public String toProducerKey() {
        if (textView == null) {
            return toString();
        } else {
            return producerId.toString() + ":" + producerSequenceId;
        }
    }

    @Override
    public String toString() {
        if (key == null) {
            if (textView != null) {
                if (textView.startsWith("ID:")) {
                    key = textView;
                } else {
                    key = "ID:" + textView;
                }
            } else {
                key = producerId.toString() + ":" + producerSequenceId;
            }
        }
        return key;
    }

    /**
     * @openwire:property version=1 cache=true
     */
    public ProducerId getProducerId() {
        return producerId;
    }

    public void setProducerId(ProducerId producerId) {
        this.producerId = producerId;
    }

    /**
     * @openwire:property version=1
     */
    public long getProducerSequenceId() {
        return producerSequenceId;
    }

    public void setProducerSequenceId(long producerSequenceId) {
        this.producerSequenceId = producerSequenceId;
    }

    /**
     * @openwire:property version=1
     */
    public long getBrokerSequenceId() {
        return brokerSequenceId;
    }

    public void setBrokerSequenceId(long brokerSequenceId) {
        this.brokerSequenceId = brokerSequenceId;
    }

    @Override
    public boolean isMarshallAware() {
        return false;
    }

    public MessageId copy() {
        MessageId copy = new MessageId(producerId, producerSequenceId);
        copy.key = key;
        copy.brokerSequenceId = brokerSequenceId;
        copy.textView = textView;
        return copy;
    }

    /**
     * @param
     * @return
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    @Override
    public int compareTo(MessageId other) {
        int result = -1;
        if (other != null) {
            result = this.toString().compareTo(other.toString());
        }
        return result;
    }
}
