#pragma once

#include "relation.h"

#include <maps/libs/common/include/exception.h>

namespace maps {
namespace wiki {
namespace contours {
namespace revision_meta {

struct Relation::Data {
    explicit Data(const revision::ObjectRevision& rev)
        : relationId(rev.id().objectId())
        , commitId(rev.id().commitId())
    {
        REQUIRE(rev.data().relationData, "Revision " << rev.id() << " is not relation");
        masterId = rev.data().relationData->masterObjectId();
        slaveId = rev.data().relationData->slaveObjectId();

        if (rev.data().deleted) {
            state = ObjectState::Deleted;
        } else if (!rev.prevId().valid()) {
            state = ObjectState::New;
        } else {
            state = ObjectState::Existing;
        }

        REQUIRE(rev.data().attributes, "Revision " << rev.id() << " has no attributes");
        const auto& attrs = *rev.data().attributes;

        auto masterCatIt = attrs.find(REL_MASTER);
        REQUIRE(masterCatIt != attrs.end(),
            "Master category is not found in relation attributes, revision " << rev.id());
        masterCategoryId = masterCatIt->second;

        auto slaveCatIt = attrs.find(REL_SLAVE);
        REQUIRE(slaveCatIt != attrs.end(),
            "Slave category is not found in relation attributes, revision " << rev.id());
        slaveCategoryId = slaveCatIt->second;

        auto roleIt = attrs.find(REL_ROLE);
        REQUIRE(roleIt != attrs.end(),
            "Role is not found in relation attributes, revision " << rev.id());
        roleId = roleIt->second;
    }

    TObjectId relationId;
    TCommitId commitId;

    ObjectState state;

    TObjectId masterId;
    TCategoryId masterCategoryId;

    TObjectId slaveId;
    TCategoryId slaveCategoryId;

    TRoleId roleId;
};

} // namespace revision_meta
} // namespace contours
} // namespace wiki
} // namespace maps
