#ifndef TILE_BASE_LOG_MESSAGE_H
#define TILE_BASE_LOG_MESSAGE_H

#pragma once
#include <cstdint>
#include <map>
#include <string>

namespace tile {
namespace log {
class Message {
public:
    typedef std::map<std::string, std::string> StringMap;

    enum Priority {
        kTrace = 0,
        kDebug,
        kInfo,
        kNotice,
        kWarning,
        kError,
        kCritical,
        kFatal,
    };

    Message();
    Message(const Message &other);
    Message(Message &&other) noexcept;
    ~Message();

    Message &operator=(const Message &other);
    Message &operator=(Message &&other) noexcept;
    void swap(Message &other);

    // getter
    inline const std::string &text() { return text_; }

    inline const std::string &source() const { return source_; }

    inline Priority priority() const { return priority_; }

    inline const std::string &thread_name() const { return thread_name_; }

    inline std::uint64_t tid() const { return tid_; }

    inline std::uint64_t pid() const { return pid_; }

    inline const char *source_file() const { return source_file_; }

    inline int source_line() const { return source_line_; }

    // setter
    inline void set_text(const std::string &text) { text_ = text; }

    inline void set_source(const std::string &source) { source_ = source; }

    inline void set_priority(Priority priority) { priority_ = priority; }

    inline void set_thread_name(const std::string &thread) { thread_name_ = thread; }

    inline void set_tid(std::uint64_t tid) { tid_ = tid; }

    inline void set_pid(std::uint64_t pid) { pid_ = pid; }

    inline void set_source_file(const char *source_file) { source_file_ = source_file; }

    inline void set_source_line(int source_line) { source_line_ = source_line; }

    // map
    const std::string &Get(const std::string &param) const;
    const std::string &Get(const std::string &param, const std::string &defult_value) const;
    const StringMap &GetAll() const;
    void Set(const std::string &param, const std::string &value);
    const std::string &operator[](const std::string &param) const;
    std::string &operator[](const std::string &param);

private:
    std::string text_;
    std::string source_;
    Priority priority_;
    std::string thread_name_;
    std::uint64_t tid_;
    std::uint64_t pid_;
    const char *source_file_;
    int source_line_;
    StringMap properties_;
};

inline void
swap(Message &lhs, Message &rhs)
{
    lhs.swap(rhs);
}
}// namespace log

}// namespace tile

#endif// TILE_BASE_LOG_MESSAGE_H
