#include <maps/wikimap/mapspro/services/mrc/tools/photo_size_generator/tools.h>

#include <maps/libs/log8/include/log8.h>
#include <maps/wikimap/mapspro/services/mrc/libs/config/include/config.h>
#include <yandex/maps/mrc/unittest/database_fixture.h>
#include <yandex/maps/wiki/common/date_time.h>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

#include <QImage>

#include <fstream>
#include <random>

namespace maps {
namespace mrc {
namespace {

const std::string PHOTO_PATH = "./tests/photo.jpg";

class StoragesFixture : public unittest::DatabaseFixture {
public:
    StoragesFixture()
        : mds_{common::Config{unittest::CONFIG_PATH}.makeMdsClient()}
    {
    }

    ~StoragesFixture()
    {
        auto txn = pool().masterReadOnlyTransaction();
        db::Gateway gtw(*txn);
        auto ids = gtw.loadFeaturesIds();
        freeMds(gtw.loadFeaturesByIds(ids));
    }

    mds::Mds& mds() { return mds_; }

private:
    mds::Mds mds_;

    void freeMds(const db::Features& features)
    {
        for (const auto& feature : features) {
            try {
                mds_.del({feature.mdsGroupId(), feature.mdsPath()});
            }
            catch (const std::exception& e) {
                // ignore
                WARN() << e.what();
            }
        }
    }
};

} // anonymous namespace

BOOST_FIXTURE_TEST_SUITE(db, StoragesFixture)

BOOST_AUTO_TEST_CASE(test_fill_sizes)
{
    {
        db::Feature feature;
        feature.setGeodeticPos({43.9996, 56.3218})
            .setHeading(15.)
            .setTimestamp(
                 chrono::parseSqlDateTime("2016-06-01 13:00:00+03"))
            .setSourceId("12345");

        auto txn = pool().masterWriteableTransaction();
        db::Gateway gtw(*txn);
        gtw.save(feature);
        std::ifstream jpeg{PHOTO_PATH};
        auto key = mds().post(std::to_string(feature.id()), jpeg).key();
        feature.setMdsGroupId(key.groupId).setMdsPath(key.path);
        gtw.save(feature);
        txn->commit();
    }

    {
        auto txn = pool().slaveTransaction();
        db::Gateway gtw(*txn);
        auto feature = gtw.loadFeaturesByIds(gtw.loadFeaturesIds()).front();
        BOOST_CHECK(!feature.width() && !feature.height());
    }

    photo::fillSizes(pool(), mds(), 500);

    {
        QImage image{PHOTO_PATH.c_str()};
        auto txn = pool().slaveTransaction();
        db::Gateway gtw(*txn);
        auto feature = gtw.loadFeaturesByIds(gtw.loadFeaturesIds()).front();
        BOOST_CHECK_EQUAL(image.width(), feature.width().get());
        BOOST_CHECK_EQUAL(image.height(), feature.height().get());
    }
}

BOOST_AUTO_TEST_SUITE_END()

} // mrc
} // maps
