#pragma once

#include <maps/libs/introspection/include/comparison.h>
#include <yandex/maps/wiki/validator/storage/exclusion_info.h>
#include <yandex/maps/wiki/validator/common.h>
#include <yandex/maps/wiki/revision/common.h>

#include <boost/optional.hpp>

#include <cstdint>
#include <vector>
#include <istream>
#include <ostream>

namespace maps::wiki {
namespace validator {

class Message;

namespace storage {

class MessageId
{
public:
    MessageId() : attributesId_(0), contentId_(0) { }

    MessageId(uint32_t attributesId, uint64_t contentId);

    uint32_t attributesId () const { return attributesId_; }
    uint64_t contentId () const { return contentId_; }

    bool empty() const
    { return !attributesId_ && !contentId_; }

    auto introspect() const
    {
        return std::tie(attributesId_, contentId_);
    }

private:
    uint32_t attributesId_;
    uint64_t contentId_;
};

std::istream& operator>>(std::istream&, MessageId&);
std::ostream& operator<<(std::ostream&, const MessageId&);

class StoredMessageDatum
{
public:
    StoredMessageDatum(
        MessageId id,
        bool isActive,
        boost::optional<ExclusionInfo> exclusionInfo,
        Message message,
        bool isViewed);

    MessageId id() const { return id_; }
    bool isActive() const { return isActive_; }
    const boost::optional<ExclusionInfo>& exclusionInfo() const { return exclusionInfo_; }
    const Message& message() const { return message_; }
    bool isViewed() const { return isViewed_; }

private:
    MessageId id_;
    bool isActive_;
    boost::optional<ExclusionInfo> exclusionInfo_;
    Message message_;
    bool isViewed_;
};

typedef std::vector<StoredMessageDatum> StoredMessageData;

using maps::introspection::operator==;

} // namespace storage
} // namespace validator
} // namespace maps::wiki
