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

#include <activemq/commands/MessageId.h>
#include <activemq/exceptions/ActiveMQException.h>
#include <activemq/state/CommandVisitor.h>
#include <decaf/internal/util/StringUtils.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/exceptions/NullPointerException.h>
#include <decaf/util/HashCode.h>
#include <sstream>

using namespace std;
using namespace activemq;
using namespace activemq::exceptions;
using namespace activemq::commands;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::internal::util;

/*
 *
 *  Command code for OpenWire format for MessageId
 *
 *  NOTE!: This file is auto generated - do not modify!
 *         if you need to make a change, please see the Java Classes in the
 *         activemq-cpp-openwire-generator module
 *
 */

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId() :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

}

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId(const MessageId& other) :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

    this->copyDataStructure(&other);
}

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId(const std::string& messageKey) :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

    this->setValue(messageKey);
}

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId(const Pointer<ProducerInfo>& producerInfo, long long producerSequenceId) :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

    this->producerId = producerInfo->getProducerId();
    this->producerSequenceId = producerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId(const Pointer<ProducerId>& producerId, long long producerSequenceId) :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

    this->producerId = producerId;
    this->producerSequenceId = producerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
MessageId::MessageId(const std::string& producerId, long long producerSequenceId) :
    BaseDataStructure(), textView(""), producerId(NULL), producerSequenceId(0), brokerSequenceId(0), key("") {

    this->producerId.reset(new ProducerId(producerId));
    this->producerSequenceId = producerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
MessageId::~MessageId() {
}

////////////////////////////////////////////////////////////////////////////////
MessageId* MessageId::cloneDataStructure() const {
    std::auto_ptr<MessageId> messageId(new MessageId());

    // Copy the data from the base class or classes
    messageId->copyDataStructure(this);

    return messageId.release();
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::copyDataStructure(const DataStructure* src) {

    // Protect against invalid self assignment.
    if (this == src) {
        return;
    }

    const MessageId* srcPtr = dynamic_cast<const MessageId*>(src);

    if (srcPtr == NULL || src == NULL) {
        throw decaf::lang::exceptions::NullPointerException(
            __FILE__, __LINE__,
            "MessageId::copyDataStructure - src is NULL or invalid");
    }

    // Copy the data of the base class or classes
    BaseDataStructure::copyDataStructure(src);

    this->setTextView(srcPtr->getTextView());
    this->setProducerId(srcPtr->getProducerId());
    this->setProducerSequenceId(srcPtr->getProducerSequenceId());
    this->setBrokerSequenceId(srcPtr->getBrokerSequenceId());
}

////////////////////////////////////////////////////////////////////////////////
unsigned char MessageId::getDataStructureType() const {
    return MessageId::ID_MESSAGEID;
}

////////////////////////////////////////////////////////////////////////////////
std::string MessageId::toString() const {

    if (key.empty()) {
        if (!textView.empty()) {
            if (textView.find_first_of("ID:") == 0) {
                key = textView;
            } else {
                key = "ID:" + textView;
            }
        } else {
            this->key = this->producerId->toString() + ":" + 
                        Long::toString(this->producerSequenceId);
        }
    }

    return this->key;
}

////////////////////////////////////////////////////////////////////////////////
bool MessageId::equals(const DataStructure* value) const {

    if (this == value) {
        return true;
    }

    const MessageId* valuePtr = dynamic_cast<const MessageId*>(value);

    if (valuePtr == NULL || value == NULL) {
        return false;
    }

    if (this->getTextView() != valuePtr->getTextView()) {
        return false;
    }
    if (this->getProducerId() != NULL) {
        if (!this->getProducerId()->equals( valuePtr->getProducerId().get())) {
            return false;
        }
    } else if (valuePtr->getProducerId() != NULL) {
        return false;
    }
    if (this->getProducerSequenceId() != valuePtr->getProducerSequenceId()) {
        return false;
    }
    if (this->getBrokerSequenceId() != valuePtr->getBrokerSequenceId()) {
        return false;
    }
    if (!BaseDataStructure::equals(value)) {
        return false;
    }
    return true;
}

////////////////////////////////////////////////////////////////////////////////
const std::string& MessageId::getTextView() const {
    return textView;
}

////////////////////////////////////////////////////////////////////////////////
std::string& MessageId::getTextView() {
    return textView;
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::setTextView(const std::string& textView) {
    this->textView = textView;
}

////////////////////////////////////////////////////////////////////////////////
const decaf::lang::Pointer<ProducerId>& MessageId::getProducerId() const {
    return producerId;
}

////////////////////////////////////////////////////////////////////////////////
decaf::lang::Pointer<ProducerId>& MessageId::getProducerId() {
    return producerId;
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::setProducerId(const decaf::lang::Pointer<ProducerId>& producerId) {
    this->producerId = producerId;
}

////////////////////////////////////////////////////////////////////////////////
long long MessageId::getProducerSequenceId() const {
    return producerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::setProducerSequenceId(long long producerSequenceId) {
    this->producerSequenceId = producerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
long long MessageId::getBrokerSequenceId() const {
    return brokerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::setBrokerSequenceId(long long brokerSequenceId) {
    this->brokerSequenceId = brokerSequenceId;
}

////////////////////////////////////////////////////////////////////////////////
int MessageId::compareTo(const MessageId& value) const {

    if (this == &value) {
        return 0;
    }

    int textViewComp = StringUtils::compareIgnoreCase(this->textView.c_str(), value.textView.c_str());
    if (textViewComp != 0) {
        return textViewComp;
    }

    int producerIdComp = this->producerId->compareTo(*(value.producerId));
    if (producerIdComp != 0) {
        return producerIdComp;
    }

    if (this->producerSequenceId > value.producerSequenceId) {
        return 1;
    } else if(this->producerSequenceId < value.producerSequenceId) {
        return -1;
    }

    if (this->brokerSequenceId > value.brokerSequenceId) {
        return 1;
    } else if(this->brokerSequenceId < value.brokerSequenceId) {
        return -1;
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////
bool MessageId::equals(const MessageId& value) const {
    return this->equals((const DataStructure*)&value);
}

////////////////////////////////////////////////////////////////////////////////
bool MessageId::operator==(const MessageId& value) const {
    return this->compareTo(value) == 0;
}

////////////////////////////////////////////////////////////////////////////////
bool MessageId::operator<(const MessageId& value) const {
    return this->compareTo(value) < 0;
}

////////////////////////////////////////////////////////////////////////////////
MessageId& MessageId::operator= (const MessageId& other) {
    this->copyDataStructure(&other);
    return *this;
}

////////////////////////////////////////////////////////////////////////////////
int MessageId::getHashCode() const {
    return decaf::util::HashCode<std::string>()(this->toString());
}

////////////////////////////////////////////////////////////////////////////////
void MessageId::setValue(const std::string& key) {

    std::string messageKey = key;

    // Parse off the sequenceId
    std::size_t p = messageKey.rfind( ':' );

    if (p != std::string::npos) {
        producerSequenceId = Long::parseLong(messageKey.substr(p + 1, std::string::npos));
        messageKey = messageKey.substr(0, p);
    }

    this->producerId.reset(new ProducerId(messageKey));
    this->key = messageKey;
}

