#pragma once

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

#include <istream>
#include <memory>
#include <ostream>
#include <string>
#include <vector>

namespace maps::wiki::validator {

enum class Severity
{
    Warning = 0,
    Error = 1,
    Critical = 2,
    Fatal = 3,

    Min = Warning,
    Max = Fatal
};

std::istream& operator>>(std::istream&, Severity& s);
std::ostream& operator<<(std::ostream&, Severity s);

enum class RegionType
{
    Important,
    Unimportant
};

std::istream& operator>>(std::istream&, RegionType& rt);
std::ostream& operator<<(std::ostream&, RegionType rt);

class Message
{
public:
    struct Attributes {
        Severity severity;
        TCheckId checkId;
        std::string description;
        RegionType regionType;

        auto introspect() const
        {
            return std::tie(severity, checkId, regionType, description);
        }
    };

    Message(
        Severity severity,
        TCheckId checkId,
        std::string description,
        RegionType regionType,
        std::string wkb,
        std::vector<RevisionID> revisionIds);

    const Attributes& attributes() const { return attributes_; }

    // Empty string represents geometry absence
    const std::string& geomWkb() const { return geomWkb_; }
    // revision ids are sorted
    const std::vector<RevisionID>& revisionIds() const { return revisionIds_; }

    auto introspect() const
    {
        return std::tie(attributes_, geomWkb_, revisionIds_);
    }

private:
    Attributes attributes_;
    std::string geomWkb_;
    std::vector<RevisionID> revisionIds_;
};

using Messages = std::vector<Message>;

using maps::introspection::operator==;
using maps::introspection::operator<;

} // namespace maps::wiki::validator
