/*
 * 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 "CMessageExt.h"
#include "CCommon.h"
#include "MQMessageExt.h"

#ifdef __cplusplus
extern "C" {
#endif
using namespace rocketmq;
const char* GetMessageTopic(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getTopic().c_str();
}
const char* GetMessageTags(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getTags().c_str();
}
const char* GetMessageKeys(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getKeys().c_str();
}
const char* GetMessageBody(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getBody().c_str();
}

int GetMessageBodyLength(CMessageExt* msgExt) {
  if (NULL == msgExt) {
    return 0;
  }
  return reinterpret_cast<MQMessageExt*>(msgExt)->getBody().length();
}

const char* GetMessageProperty(CMessageExt* msg, const char* key) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getProperty(key).c_str();
}
const char* GetMessageId(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL;
  }
  return ((MQMessageExt*)msg)->getMsgId().c_str();
}

int GetMessageDelayTimeLevel(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getDelayTimeLevel();
}

int GetMessageQueueId(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getQueueId();
}

int GetMessageReconsumeTimes(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getReconsumeTimes();
}

int GetMessageStoreSize(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getStoreSize();
}

long long GetMessageBornTimestamp(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getBornTimestamp();
}

long long GetMessageStoreTimestamp(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getStoreTimestamp();
}

long long GetMessageQueueOffset(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getQueueOffset();
}

long long GetMessageCommitLogOffset(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getCommitLogOffset();
}

long long GetMessagePreparedTransactionOffset(CMessageExt* msg) {
  if (msg == NULL) {
    return NULL_POINTER;
  }
  return ((MQMessageExt*)msg)->getPreparedTransactionOffset();
}
#ifdef __cplusplus
};
#endif
