#pragma once

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

namespace maps::wiki::revision {

class PreparedCommitAttributes {
public:
    PreparedCommitAttributes(pqxx::transaction_base& work, const Attributes& attrs);

    const Hstore& hstoreData() const { return hstoreData_; }
    const Attributes& attributes() const { return attributes_; }
    Attributes& attributes() { return attributes_; }

private:
    Attributes attributes_;
    Hstore hstoreData_;
};

class CommitData {
public:
    static CommitData create(
        pqxx::transaction_base& work,
        DBID branchId,
        UserID uid,
        const PreparedCommitAttributes& attributes);

    static CommitData load(const pqxx::row& row);


    bool inTrunk() const { return trunk; }
    bool inStable() const { return stableBranchId != TRUNK_BRANCH_ID; }

    bool merged() const { return inTrunk() && inStable(); }

    void checkForUpdate(BranchType type) const;

    DBIDSet revertedCommitIds() const;
    DBIDSet revertedDirectlyCommitIds() const;
    DBIDSet revertingCommitIds() const;
    OptionalDBID revertingDirectlyCommitId() const;

    const Attributes& attributes() const { return attributes_; }
    void setAttributes(
        pqxx::transaction_base& work, PreparedCommitAttributes attributes);
    void addAttribute(
        pqxx::transaction_base& work,
        const std::string& key,
        const std::string& value);

    const std::string createdAt;
    const CommitState state;
    const DBID id;
    const DBID approveOrder;
    const UserID createdBy;
    const DBID stableBranchId;
    const bool trunk;

protected:
    // for load() and tests
    CommitData(
        DBID commitId,
        DBID approveOrder,
        CommitState state,
        UserID uid,
        Attributes attributes,
        std::string createdAt,
        DBID stableBranchId,
        bool isTrunk);

private:
    // for create()
    CommitData(
        DBID commitId,
        UserID uid,
        Attributes attributes,
        std::string createdAt,
        DBID branchId);

    const bool loaded_;
    Attributes attributes_;
};

} // namespace maps::wiki::revision
