#include <maps/wikimap/mapspro/services/tasks_feedback/src/schedule_feedback_worker/lib/fbapi/traits.h>
#include <maps/libs/http/include/test_utils.h>
#include <util/stream/output.h>
#include <sstream>

#include <library/cpp/testing/unittest/env.h>
#include <library/cpp/testing/unittest/registar.h>

template <>
void Out<maps::json::Value>(
    IOutputStream& os,
    const maps::json::Value& json)
{
    std::ostringstream ostr;
    ostr << json;
    os << ostr.str();
}

namespace maps::wiki::schedule_feedback::tests {

namespace sf = social::feedback;
namespace sft = social::feedback::tests;

struct UrlWithVerdict {
    std::string url;
    std::string verdict;
};

class MockCleanwebRequest {
public:
    MockCleanwebRequest(std::vector<UrlWithVerdict> photos)
        : photos_(std::move(photos))
        , counter_(0)
    {}

    std::function<maps::http::MockResponse(const maps::http::MockRequest&)> checkRequest()
    {
        return [this](const maps::http::MockRequest& request) {
            UNIT_ASSERT(counter_ < photos_.size());
            UNIT_ASSERT_VALUES_EQUAL(
                maps::json::Value::fromString(request.body),
                maps::json::Value::fromString(R"({
                    "id": ")" + photos_[counter_].url + R"(",
                    "jsonrpc": "2.0",
                    "method": "process",
                    "params": {
                        "body": {
                            "image_url": ")" + photos_[counter_].url + R"("
                        },
                        "key": "maps_feedback_photo",
                        "service": "maps_feedback",
                        "type": "image"
                    }
                })")
            );
            const std::string response = R"({
                "jsonrpc": "2.0",
                "id": ")" + photos_[counter_].url + R"(",
                "result": {
                    "verdicts": [
                        {
                            "name": ")" + photos_[counter_].verdict + R"(",
                            "subsource": "image",
                            "value": true,
                            "entity": "image",
                            "source": "clean-web",
                            "key": "maps_feedback_photo"
                        }
                    ],
                    "errors": {}
                }
            })";
            ++counter_;
            return response;
        };
    }

private:
    std::vector<UrlWithVerdict> photos_;
    size_t counter_;
};

Y_UNIT_TEST_SUITE(has_bad_photos_ut) {

Y_UNIT_TEST(bad_photos)
{
    json::Value photoUrls = json::Value::fromString(R"([
        "http://photourl1",
        "http://photourl2"
    ])");
    MockCleanwebRequest mockCleanwebRequest({
        {"http://photourl1", "media_ok"},
        {"http://photourl2", "media_auto_bad"}
    });

    auto mockGetStatusesHandle = maps::http::addMock(
        "http://router-prod.clean-web.yandex.net/v2",
        mockCleanwebRequest.checkRequest()
    );

    UNIT_ASSERT(internal::hasBadPhotos(photoUrls));
}

Y_UNIT_TEST(no_bad_photos)
{
    json::Value photoUrls = json::Value::fromString(R"([
        "http://photourl1",
        "http://photourl2"
    ])");
    MockCleanwebRequest mockCleanwebRequest({
        {"http://photourl1", "media_ok"},
        {"http://photourl2", "ok"}
    });

    auto mockGetStatusesHandle = maps::http::addMock(
        "http://router-prod.clean-web.yandex.net/v2",
        mockCleanwebRequest.checkRequest()
    );

    UNIT_ASSERT(!internal::hasBadPhotos(photoUrls));
}

} // has_bad_photos_ut suite

} // namespace maps::wiki::schedule_feedback::tests
