#pragma once

#include <yandex/maps/wiki/diffalert/revision/aoi_diff_context.h>
#include "fully_loaded_object_impl.h"

#include <boost/optional.hpp>

namespace maps {
namespace wiki {
namespace diffalert {

enum class SplitStatus
{
    None,
    Created,
    Modified
};

struct AoiDiffData
{
    revision::DBID objectId;
    boost::optional<FullyLoadedObjectData> oldObject;
    boost::optional<FullyLoadedObjectData> newObject;
    SplitStatus splitStatus;
    bool geomChanged;
    bool categoryChanged;
    bool attrsChanged;
    Relations relationsAdded;
    Relations relationsDeleted;
    Relations tableAttrsAdded;
    Relations tableAttrsDeleted;
};

class AoiDiffContext::Impl
{
public:
    explicit Impl(AoiDiffData data)
        : geomChanged(data.geomChanged)
        , categoryChanged(data.categoryChanged)
        , attrsChanged(data.attrsChanged)
        , relationsAdded(std::move(data.relationsAdded))
        , relationsDeleted(std::move(data.relationsDeleted))
        , tableAttrsAdded(std::move(data.tableAttrsAdded))
        , tableAttrsDeleted(std::move(data.tableAttrsDeleted))
    {
        if (data.oldObject) {
            oldObject.reset(new FullyLoadedObject(
                PImplFactory::create<FullyLoadedObject>(std::move(*data.oldObject))));
        }
        if (data.newObject) {
            newObject.reset(new FullyLoadedObject(
                PImplFactory::create<FullyLoadedObject>(std::move(*data.newObject))));
        }
    }

    const FullyLoadedObject& anyObject() const { return newObject ? *newObject : *oldObject; }

    std::unique_ptr<FullyLoadedObject> oldObject;
    std::unique_ptr<FullyLoadedObject> newObject;
    bool geomChanged;
    bool categoryChanged;
    bool attrsChanged;
    Relations relationsAdded;
    Relations relationsDeleted;
    Relations tableAttrsAdded;
    Relations tableAttrsDeleted;
};

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