/*
 * 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.
 */
#ifndef __MESSAGE_H__
#define __MESSAGE_H__

#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "RocketMQClient.h"

namespace rocketmq {
//<!***************************************************************************
class ROCKETMQCLIENT_API MQMessage {

 public:
  MQMessage();
  MQMessage(const std::string& topic, const std::string& body);
  MQMessage(const std::string& topic, const std::string& tags, const std::string& body);
  MQMessage(const std::string& topic, const std::string& tags, const std::string& keys,
            const std::string& body);
  MQMessage(const std::string& topic, const std::string& tags, const std::string& keys,
            const int flag, const std::string& body, bool waitStoreMsgOK);

  virtual ~MQMessage();
  MQMessage(const MQMessage& other);
  MQMessage& operator=(const MQMessage& other);

  void setProperty(const std::string& name, const std::string& value) ;
  const std::string & getProperty(const std::string& name) const;

  const std::string &getTopic() const;
  void setTopic(const std::string& topic);
  void setTopic(const char* body, int len);

  const std::string &getTags() const;
  void setTags(const std::string& tags);

  const std::string &getKeys() const;
  void setKeys(const std::string& keys);
  void setKeys(const std::vector<std::string>& keys);

  int getDelayTimeLevel() const;
  void setDelayTimeLevel(int level);

  bool isWaitStoreMsgOK() const;
  void setWaitStoreMsgOK(bool waitStoreMsgOK);

  int getFlag() const;
  void setFlag(int flag);

  int getSysFlag() const;
  void setSysFlag(int sysFlag);

  const std::string &getBody() const;

  void setBody(const char* body, int len);
  void setBody(const std::string& body);

  std::map<std::string, std::string> getProperties() const;
  void setProperties(std::map<std::string, std::string>& properties);

  const std::string toString() const {
    std::stringstream ss;
    std::string tags = getTags();
    ss << "Message [topic=" << m_topic << ", flag=" << m_flag
       << ", tag=" << tags << "]";
    return ss.str();
  }

 protected:
  friend class MQDecoder;
  void setPropertyInternal(const std::string& name, const std::string& value);
  void setPropertiesInternal(std::map<std::string, std::string>& properties);

  void Init(const std::string& topic, const std::string& tags, const std::string& keys,
            const int flag, const std::string& body, bool waitStoreMsgOK);

 public:
  static const std::string PROPERTY_KEYS;
  static const std::string PROPERTY_TAGS;
  static const std::string PROPERTY_WAIT_STORE_MSG_OK;
  static const std::string PROPERTY_DELAY_TIME_LEVEL;
  static const std::string PROPERTY_RETRY_TOPIC;
  static const std::string PROPERTY_REAL_TOPIC;
  static const std::string PROPERTY_REAL_QUEUE_ID;
  static const std::string PROPERTY_TRANSACTION_PREPARED;
  static const std::string PROPERTY_PRODUCER_GROUP;
  static const std::string PROPERTY_MIN_OFFSET;
  static const std::string PROPERTY_MAX_OFFSET;
  
  static const std::string PROPERTY_BUYER_ID;
  static const std::string PROPERTY_ORIGIN_MESSAGE_ID;
  static const std::string PROPERTY_TRANSFER_FLAG;
  static const std::string PROPERTY_CORRECTION_FLAG;
  static const std::string PROPERTY_MQ2_FLAG;
  static const std::string PROPERTY_RECONSUME_TIME;
  static const std::string PROPERTY_MSG_REGION;
  static const std::string PROPERTY_TRACE_SWITCH;
  static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX;
  static const std::string PROPERTY_MAX_RECONSUME_TIMES;
  static const std::string PROPERTY_CONSUME_START_TIMESTAMP;
  static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET;
  static const std::string PROPERTY_TRANSACTION_CHECK_TIMES;
  static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS;

  static const std::string KEY_SEPARATOR;

 protected:
  int m_sysFlag;

 private:
  std::string m_topic;
  int m_flag;
  std::string m_body;
  std::map<std::string, std::string> m_properties;
};
//<!***************************************************************************
}  // namespace rocketmq
#endif
