#pragma once

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

#include <istream>
#include <ostream>
#include <tuple>
#include <vector>
#include <utility>

namespace maps::wiki::revision {

class RevisionID;
using RevisionIds = std::vector<RevisionID>;

std::istream& operator >> (std::istream& is, RevisionID& rid);
std::ostream& operator << (std::ostream& os, const RevisionID& rid);

class RevisionID {
public:
    // empty ID
    RevisionID() = default;

    // valid ID
    RevisionID(DBID objectId, DBID commitId);

    DBID objectId() const { return objectId_; }
    DBID commitId() const { return commitId_; } // 0 - for new commit

    bool empty() const { return !objectId_ && !commitId_; }
    bool valid() const { return objectId_ && commitId_; }

    // external object id to insert into new commit
    static RevisionID createNewID(DBID objectId) { return RevisionID(objectId); }

private:
    explicit RevisionID(DBID objectId);

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

private:
    DBID objectId_{0};
    DBID commitId_{0};
};

inline std::tuple<DBID, DBID> introspect(const RevisionID& id)
{
    return std::tuple<DBID, DBID>(id.objectId(), id.commitId());
}

using introspection::operator==;
using introspection::operator!=;
using introspection::operator<;
using introspection::operator<=;
using introspection::operator>;
using introspection::operator>=;

} // namespace maps::wiki::revision
