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

#include <map>

namespace maps {
namespace wiki {
namespace topo {

std::string
errorCodeToString(ErrorCode errorCode)
{
    static const std::map<ErrorCode, std::string> reprs = {
        { ErrorCode::Unspecified, "Unspecified"},
        { ErrorCode::Unsupported, "Unsupported"},

        // graph restrictions
        { ErrorCode::SelfIntersection, "SelfIntersection"},
        { ErrorCode::SelfOverlap, "SelfOverlap"},

        // Topology restrictions
        { ErrorCode::InvalidRestrictions, "InvalidRestrictions"},
        { ErrorCode::TooManyIntersectionsWithNetwork, "TooManyIntersectionsWithNetwork"},
        { ErrorCode::TooManyIntersectionsWithElement, "TooManyIntersectionsWithElement"},
        { ErrorCode::DegenerateSegment, "DegenerateSegment"},
        { ErrorCode::TooLongSegment, "TooLongSegment"},
        { ErrorCode::DegenerateEdge, "DegenerateEdge"},
        { ErrorCode::TooLongEdge, "TooLognEdge"},
        { ErrorCode::MergeOfOverlappedEdgesForbidden, "MergeOfOverlappingEdgesForbidden"},
        { ErrorCode::NodeDeletionForbidden, "NodeDeletionForbidden"},

        // unexpected situations
        { ErrorCode::UnexpectedIntersection, "UnexpectedIntersectionWithElement"},
        { ErrorCode::AmbiguousSnapping, "AmbiguousSnapping"}
    };

    auto it = reprs.find(errorCode);
    REQUIRE(it != reprs.end(), "Unknown error code: " << (int)(errorCode));
    return it->second;
}

namespace {

std::string
pointToString(const geolib3::Point2& location)
{
    std::ostringstream os;
    os << " at point (" << location.x() << ", " << location.y() << "): ";
    return os.str();
}

} // namespace

GeomProcessingErrorWithLocation::GeomProcessingErrorWithLocation(
        ErrorCode errorCode,
        const geolib3::Point2& location)
    : GeomProcessingError(errorCode, pointToString(location))
    , location_(location)
{}

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