#include "delete_edge.h"

#include "process_events.h"
#include "../cache_impl.h"
#include "../events_data.h"
#include "../editor_impl.h"
#include "../graph.h"

#include <yandex/maps/wiki/topo/storage.h>
#include <yandex/maps/wiki/topo/events.h>
#include <yandex/maps/wiki/topo/exception.h>

namespace maps {
namespace wiki {
namespace topo {

DeleteEdgeOperation::DeleteEdgeOperation(
        const Callbacks& callbacks, CacheImpl& cache, EdgeID edgeId)
    : Operation(callbacks, cache)
    , edgeId_(edgeId)
{
    REQUIRE(edgeId_, " invalid edge id");
}

void DeleteEdgeOperation::operator () ()
{
    cache_.loadByEdges( EdgeIDSet{edgeId_} );

    Edge& edge = cache_.graph().edge(edgeId_);
    DeleteEdgeEventData eventData(edgeId_, edge.startNode(), edge.endNode());

    ProcessEvents process(cache_, callbacks_);

    DeleteEdgeRequest request(eventData);
    callbacks_.deleteEdge.callback().processRequest(request);

    process(eventData);

    cache_.loadByNodes({eventData.startNodeId, eventData.endNodeId});

    if (cache_.graph().node(eventData.startNodeId).isIsolated() &&
        cache_.storage().nodeCanBeDeleted(eventData.startNodeId))
    {
        cache_.graph().deleteNode(eventData.startNodeId);
        cache_.storage().deleteNode(eventData.startNodeId);
    }
    if (eventData.startNodeId != eventData.endNodeId &&
        cache_.graph().node(eventData.endNodeId).isIsolated() &&
        cache_.storage().nodeCanBeDeleted(eventData.endNodeId))
    {
        cache_.graph().deleteNode(eventData.endNodeId);
        cache_.storage().deleteNode(eventData.endNodeId);
    }

    callbacks_.deleteEdge.callback().processEvent(DeleteEdgeEvent(eventData));
}

} // namespace topo
} // namespace wiki
} // namespace maps
