#include <maps/wikimap/mapspro/services/mrc/libs/toloka_manager/include/taxonomy.h>
#include <maps/libs/json/include/builder.h>
#include <maps/libs/json/include/value.h>

namespace maps {
namespace mrc {
namespace toloka {

template <>
TaxonomyInput parseJson(const json::Value& jsonInput)
{
    return {jsonInput[FIELD_IMAGE].as<std::string>(),
            common::ImageBox::fromJson(jsonInput[FIELD_BBOX])};
}

template <>
TaxonomyOutput parseJson(const json::Value& jsonOutput)
{
    return {jsonOutput[FIELD_RESULT].as<std::string>()};
}

/**
 * TaxonomyInput implementation
 */
TaxonomyInput::TaxonomyInput(std::string imageUrl, const common::ImageBox& bbox)
    : imageUrl_(std::move(imageUrl)), bbox_(bbox)
{
}

const std::string& TaxonomyInput::imageUrl() const { return imageUrl_; }

const common::ImageBox& TaxonomyInput::bbox() const { return bbox_; }

TaxonomyInput& TaxonomyInput::setImageUrl(std::string url)
{
    imageUrl_ = std::move(url);
    return *this;
}

void TaxonomyInput::json(json::ObjectBuilder builder) const
{
    builder[FIELD_IMAGE] = imageUrl();
    builder[FIELD_BBOX] = bbox();
}

/**
 * TaxonomyOutput implementation
 */
TaxonomyOutput::TaxonomyOutput(std::string result)
    : result_(std::move(result))
{
}

const std::string& TaxonomyOutput::result() const { return result_; }

void TaxonomyOutput::json(json::ObjectBuilder builder) const
{
    builder[FIELD_RESULT] = result();
}

bool operator==(const TaxonomyOutput& lhs, const TaxonomyOutput& rhs) {
    return lhs.introspect() == rhs.introspect();
}

bool operator<(const TaxonomyOutput& lhs, const TaxonomyOutput& rhs) {
    return lhs.introspect() < rhs.introspect();
}

std::ostream& operator<<(std::ostream& out, const TaxonomyOutput& taskOutput) {
    json::Builder builder(out);
    builder << [&](json::ObjectBuilder b) {
        taskOutput.json(b);
    };
    return out;
}

} // namespace toloka
} // namespace mrc
} // namespace maps
