#pragma once

#include <yandex/maps/wiki/diffalert/diff_context.h>
#include <yandex/maps/wiki/diffalert/revision/snapshot.h>
#include <yandex/maps/wiki/diffalert/revision/commit_filter.h>

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

#include <memory>
#include <vector>

namespace maps {
namespace pgpool3 {

class Pool;

} // namespace pgpool3
namespace wiki {
namespace revision {

class Branch;
class SnapshotId;

} // namespace revision
namespace diffalert {

class LongtaskDiffContext;
class EditorConfig;

class CompareSnapshotsResult
{
public:
    struct Impl;
    explicit CompareSnapshotsResult(Impl&& impl);

    CompareSnapshotsResult(CompareSnapshotsResult&&) noexcept;
    CompareSnapshotsResult& operator=(CompareSnapshotsResult&&) noexcept;
    ~CompareSnapshotsResult();

    const std::vector<LongtaskDiffContext>& diffContexts() const&;
    std::vector<LongtaskDiffContext>&& diffContexts() &&;

    const TIds& badObjects() const;
    const TIds& badRelations() const;

private:
    std::unique_ptr<Impl> impl_;
};

class LongtaskDiffContext : public DiffContext
{
public:
    class Impl;
    explicit LongtaskDiffContext(Impl&& impl);

    // Result references provided connection pools
    static CompareSnapshotsResult compareSnapshots(
        const revision::Branch& oldBranch,
        const revision::SnapshotId& oldSnapshotId,
        const revision::Branch& newBranch,
        const revision::SnapshotId& newSnapshotId,
        pgpool3::Pool& tdsConnPool,
        pgpool3::Pool& viewConnPool,
        const EditorConfig& config,
        const CommitFilter& commitsToExcludeFilter = CommitFilter());

    LongtaskDiffContext(LongtaskDiffContext&&) noexcept;
    LongtaskDiffContext& operator=(LongtaskDiffContext&&) noexcept;
    virtual ~LongtaskDiffContext();

    virtual TId objectId() const;
    virtual const std::string& categoryId() const;

    virtual OptionalObject oldObject() const;
    virtual OptionalObject newObject() const;

    virtual LongtaskSnapshot& oldSnapshot() const;
    virtual LongtaskSnapshot& newSnapshot() const;

    virtual bool categoryChanged() const;
    virtual bool attrsChanged() const;
    virtual bool geomChanged() const;

    virtual const Relations& relationsAdded() const;
    virtual const Relations& relationsDeleted() const;

    virtual const Relations& tableAttrsAdded() const;
    virtual const Relations& tableAttrsDeleted() const;

private:
    std::unique_ptr<Impl> impl_;
};

} // namespace diffalert
} // namespace wiki
} // namespace maps
